He
HeliumTS
Note:

HeliumTS is under pre-beta and active development. Expect bugs and breaking changes. If you find any issues, please report them in our GitHub

A stable release is planned for early December 2025.

Production Deployment

Platform Compatibility

Helium uses WebSocket-based RPC for real-time communication between client and server. This architecture requires a persistent server process, which affects your choice of hosting platform.

✅ Fully Compatible Platforms

These platforms support persistent Node.js servers and WebSocket connections:

PlatformWebSocket SupportRPC SupportNotes
Digital Ocean App PlatformRecommended. Full support for all features
RailwayExcellent for quick deployments
RenderFree tier available
Fly.ioGreat for edge deployments
AWS EC2 / ECSFull control, requires more setup
Google Cloud RunSet --session-affinity for WebSockets
HerokuUse heroku labs:enable http-session-affinity
Self-hosted / VPSDocker or direct Node.js

⚠️ Limited Compatibility Platforms

These platforms have fundamental limitations that affect Helium features:

PlatformIssueWhat WorksWhat Doesn't Work
VercelServerless (no persistent connections)SSG pages, static assetsWebSocket RPC, direct URL navigation to dynamic routes
NetlifyServerless (no persistent connections)SSG pages, static assetsWebSocket RPC, direct URL navigation to dynamic routes
Cloudflare PagesServerlessSSG pages, static assetsWebSocket RPC

Using Helium on Vercel/Netlify (Limited Mode)

If you must use Vercel or Netlify, Helium can work in SSG-only mode:

  1. Pre-render all pages using SSG (see SSG documentation)
  2. Avoid RPC calls - use external APIs or pre-fetched data instead
  3. Add SPA fallback with a vercel.json:
1{
2 "rewrites": [
3 { "source": "/(.*)", "destination": "/index.html" }
4 ]
5}

Note: Even with SPA fallback, refreshing a page or navigating directly to a URL (not from the home page) may fail if that route requires server-side data.


Configuration Files in Production

When deploying your Helium application, the framework needs to load your helium.config file. The build process automatically handles TypeScript config files for you.

Automatic Config Transpilation

During helium build, the framework:

  1. If helium.config.ts exists: Automatically transpiles it to dist/helium.config.js
  2. If helium.config.js exists: Copies it to dist/helium.config.js
  3. If helium.config.mjs exists: Copies it to dist/helium.config.mjs

When you run helium start, the production server looks for the config file in the dist directory first, then falls back to the project root.

Deployment Structure

After running helium build, your deployment should include:

1your-app/
2├── dist/
3│ ├── server.js # Bundled server code
4│ ├── helium.config.js # Transpiled config (if you had .ts)
5│ ├── index.html # Client entry
6│ └── assets/ # Client bundles
7├── package.json
8└── node_modules/

Platform-Specific Instructions

Digital Ocean App Platform

  1. Set build command: npm run build
  2. Set run command: npm run start (or directly: helium start)
  3. Ensure node_modules is included in the deployment
  4. Add environment variables in Settings → App-Level Environment Variables
    • Example: DATABASE_URL, JWT_SECRET, PORT, etc.
    • These will be available in process.env automatically

Docker

1FROM node:18-alpine
2
3WORKDIR /app
4
5# Copy package files
6COPY package*.json ./
7RUN npm ci --only=production
8
9# Copy built files
10COPY dist ./dist
11
12# The config file should be in dist/ after build
13EXPOSE 3000
14
15CMD ["node", "dist/server.js"]

Vercel / Netlify (Limited Support)

⚠️ Important

Vercel and Netlify are serverless platforms that do not support persistent WebSocket connections. This means:

  • WebSocket-based RPC will not work
  • Direct URL navigation to routes (other than the home page) will return 404 errors
  • Only pre-rendered SSG pages and SPA navigation from the home page work correctly

If you need full Helium functionality, use a platform that supports persistent servers (see Platform Compatibility above).

For SSG-only deployments on Vercel, add a vercel.json:

1{
2 "rewrites": [
3 { "source": "/(.*)", "destination": "/index.html" }
4 ]
5}

For Netlify, add a _redirects file in your public folder:

1/* /index.html 200

Manual Config Conversion

If you prefer to use .js config files in production without transpilation:

  1. Rename your config file:
    %mv helium.config.ts helium.config.js
  2. Update the syntax to JavaScript:
    1// helium.config.js
    2export default {
    3 trustProxyDepth: 1,
    4 rpc: {
    5 compression: {
    6 enabled: true,
    7 threshold: 1024,
    8 },
    9 security: {
    10 maxConnectionsPerIP: 10,
    11 maxMessagesPerWindow: 100,
    12 rateLimitWindowMs: 60000,
    13 tokenValidityMs: 30000,
    14 },
    15 },
    16};

Environment Variables

Client-Side Environment Variables

To expose environment variables to the browser, prefix them with HELIUM_PUBLIC_:

%# .env or platform environment variables
%HELIUM_PUBLIC_APP_NAME=My App
%HELIUM_PUBLIC_API_URL=https://api.example.com
%HELIUM_PUBLIC_FEATURE_FLAG=true

Access them in your React components using import.meta.env:

1function MyComponent() {
2 const appName = import.meta.env.HELIUM_PUBLIC_APP_NAME;
3 const apiUrl = import.meta.env.HELIUM_PUBLIC_API_URL;
4 const featureEnabled = import.meta.env.HELIUM_PUBLIC_FEATURE_FLAG === 'true';
5
6 return <div>{appName} - {apiUrl}</div>;
7}

Important:

  • Build-time injection: Environment variables are injected at build time by Vite. Make sure your hosting platform (Digital Ocean, Vercel, etc.) has the environment variables set before the build runs.
  • Only HELIUM_PUBLIC_* variables are exposed to the browser for security reasons
  • Server-side code can access all environment variables via process.env

Most cloud platforms (Digital Ocean, Vercel, Heroku, etc.) provide their own environment variable management. This is the recommended approach for production:

Digital Ocean App Platform:

  1. Go to your app's Settings → App-Level Environment Variables
  2. Add your variables (e.g., DATABASE_URL, API_KEY, HELIUM_PUBLIC_APP_NAME)
  3. They'll be automatically injected into process.env and exposed to the client if prefixed with HELIUM_PUBLIC_

Advantages:

  • No need to deploy .env files
  • Variables are managed securely by the platform
  • Different values per environment (staging/production)
  • No risk of committing secrets to git
  • No rebuild required when changing client-side variables

Using .env Files in Production

If you need to deploy .env files, you have two options:

Option 1: Include in deployment

Add .env files to your deployment artifacts. For Digital Ocean:

  1. Remove .env from .gitignore (only for non-secret configs)
  2. Or manually upload .env files via the platform UI

Option 2: Copy during build

Update your build process to copy .env files:

1{
2 "scripts": {
3 "build": "helium build && cp .env* dist/ 2>/dev/null || true"
4 }
5}

Then in production, run from the dist directory:

%cd dist && node server.js

Environment Variable Priority

Helium loads environment variables in this order (highest to lowest priority):

  1. Platform environment variables (from hosting provider)
  2. .env.production.local
  3. .env.local
  4. .env.production
  5. .env

Existing process.env values are never overridden by .env files.

Troubleshooting

Warning: "No .env files found or no variables loaded"

This warning appears when:

  1. No .env files exist (normal if using platform variables)
  2. .env files exist but contain no variables
  3. Working directory doesn't contain .env files

Solutions:

  • If using platform environment variables: Ignore this warning, it's expected
  • If using .env files: Ensure they're in the same directory as server.js
  • Check process.cwd() matches your .env file location

Error: "Unknown file extension .ts"

This means the config file wasn't transpiled during build. Ensure:

  1. Your config file is at the project root as helium.config.ts
  2. You ran helium build before deploying
  3. The dist/helium.config.js file exists after build

Config not loading in production

Check that:

  1. The config file is in the dist directory
  2. You're running from the correct directory (where dist/ exists)
  3. The HELIUM_CONFIG_DIR environment variable isn't incorrectly set