Migrating from Helium 2.x to 3.0
This guide provides detailed step-by-step instructions for migrating your Helium application from version 2.x to 3.0.
Overview
Helium 3.0 represents a significant modernization of the framework, primarily focused on updating the build tooling and SSR framework from vite-plugin-ssr to vike, along with dependency updates for security and performance.
What Changed and Why
1. vite-plugin-ssr → Vike Migration
- What: The SSR framework was renamed from
vite-plugin-ssrtovike - Why: Official rebrand by the maintainer, improved API, better documentation
- Impact: Import statements and some configuration patterns changed
2. Vite 3 → Vite 5
- What: Build tool upgraded from Vite 3.x to Vite 5.x
- Why: Performance improvements, security fixes, future compatibility
- Impact: Faster builds, improved developer experience
3. Dependency Updates
- Storybook: v7 → v8.6.14 (component development)
- i18next: v21 → v23.16.8 (internationalization)
- react-i18next: v11 → v13.5.0 (React i18n bindings)
- GraphQL: 16.6.0 → 16.11.0 (security fixes)
- Why: Security vulnerabilities, deprecated APIs, performance improvements
4. Enhanced Configuration Management
- What: Vite configuration expanded and improved in
helium-serverpackage - Why: Added critical build settings (manifest, ssr.noExternal, resolve.dedupe) and factory function pattern
- Impact: More comprehensive base config, prevents misconfiguration
Prerequisites
Before starting the migration:
- Backup your project: Create a git branch or backup
- Node.js 18.20.7: REQUIRED - Helium 3.0 requires Node.js 18.20.7 (check with
node -v) - npm 8.19.2+: npm 8.19.2 or higher (check with
npm -v) - Clean git state: Commit or stash any pending changes
- Working 2.x app: Ensure your current app builds and runs successfully
⚠️ Important: Node.js 18.20.7 is required for Helium 3.0 (Vike and Vite 5 both require Node 18+). Helium 2.7 and earlier required Node.js 16.18.1 or higher. You must upgrade to Node 18.20.7 before migrating to 3.0.
Migration Steps
Step 1: Update Dependencies
1.1 Update package.json
Update your package.json dependencies to use 3.x versions:
{
"dependencies": {
// Core Helium packages - update to 3.x
"@thoughtindustries/helium-server": "^3.0.0",
// Component packages - update to 2.x (if using)
"@thoughtindustries/catalog": "^2.0.0",
"@thoughtindustries/content": "^2.0.0",
"@thoughtindustries/user": "^2.0.0",
"@thoughtindustries/cart": "^2.0.0",
"@thoughtindustries/featured-content": "^2.0.0",
"@thoughtindustries/dashboard-stats": "^2.0.0",
// Build tools
"vike": "0.4.195", // Changed from vite-plugin-ssr
"vite": "^5.4.11", // Upgraded from 3.x/4.x
// Updated dependencies
"i18next": "^23.16.8",
"react-i18next": "^13.5.0",
"graphql": "^16.11.0"
},
"devDependencies": {
"@mdx-js/rollup": "^2.1.3",
"tsup": "^8.5.0"
}
}
1.2 Remove old dependencies
Remove vite-plugin-ssr if it's explicitly listed:
npm uninstall vite-plugin-ssr
1.3 Install new dependencies
# Clean install to avoid conflicts
rm -rf node_modules package-lock.json
npm install
Step 2: Add Required Build Scripts
Helium 3.0 requires additional build scripts for manifest generation. These scripts ensure proper deployment to Cloudflare Workers.
2.1 Download the scripts from the template package
# Download the template package
npm pack @thoughtindustries/helium-template@latest
# Extract the scripts folder
tar -xzf thoughtindustries-helium-template-*.tgz package/scripts
# Move scripts to your project root
mv package/scripts ./scripts
# Clean up
rm -rf package thoughtindustries-helium-template-*.tgz
2.2 Update your build:vite script
In your package.json, update the build:vite script to include manifest generation:
Before:
"build:vite": "vite build",
After:
"build:vite": "vite build && node scripts/generate-manifest.js && node scripts/generate-asset-tags.js",
2.3 Verify the scripts folder
Your project should now have:
your-project/
├── scripts/
│ ├── generate-manifest.js
│ └── generate-asset-tags.js
├── package.json
└── ...
Why is this needed?
generate-manifest.jscreatesdist/client/manifest.jsonrequired by the deployment processgenerate-asset-tags.jscreatesdist/asset-tags.jsonfor asset loading- Without these, deployment will fail with missing manifest errors
Step 3: Update Import Statements
3.1 Update vite-plugin-ssr imports to vike
Find and replace all occurrences in your codebase:
In renderer/_default.page.server.tsx:
- import { escapeInject, dangerouslySkipEscape } from 'vite-plugin-ssr/server';
+ import { escapeInject, dangerouslySkipEscape } from 'vike/server';
In vite.config.ts (if you have custom config):
- import ssr from 'vite-plugin-ssr/plugin';
+ import vike from 'vike/plugin';
- plugins: [react(), ssr()]
+ plugins: [react(), vike()]
Step 4: Update Vite Configuration
4.1 Simplify vite.config.ts
Old 2.x approach:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import ssr from 'vite-plugin-ssr/plugin';
export default defineConfig({
plugins: [react(), ssr()],
build: {
manifest: true
},
optimizeDeps: {
include: ['dayjs', 'universal-cookie']
},
envPrefix: 'HELIUM_PUBLIC_',
ssr: {
noExternal: ['@apollo/client', 'graphql', 'use-debounce']
},
resolve: {
dedupe: ['@apollo/client']
}
});
New 3.x approach:
import { createVikeConfig } from '@thoughtindustries/helium-server';
import { defineConfig } from 'vite';
export default defineConfig(async () => {
// Get base config with all critical settings included
const config = await createVikeConfig();
// Add any custom configuration here if needed
// For example, custom aliases, additional plugins, etc.
return config;
});
Key Benefits:
- ✅ Critical settings (
manifest,envPrefix,ssr.noExternal,resolve.dedupe) are now centralized - ✅ Can't accidentally break production deployment settings
- ✅ Much simpler configuration - just call the factory function
- ✅ ESM/CJS compatibility handled automatically
- ✅ All necessary plugins already included (React, Vike, MDX support)
Step 5: Update Environment Variables
The envPrefix is now centralized in helium-server. Ensure your environment variables use the HELIUM_PUBLIC_ prefix:
Environment variables that should be exposed to the browser:
HELIUM_PUBLIC_API_KEY=your-key
HELIUM_PUBLIC_FEATURE_FLAG=true
Variables without the prefix are server-only:
HELIUM_ENDPOINT=https://your-instance.thoughtindustries.com/helium/api/graphql
Step 6: Update passToClient (Optional New Fields)
Two new optional fields have been added to passToClient in 3.0:
In renderer/_default.page.server.tsx:
export const passToClient = [
'pageProps',
'urlParsed', // REQUIRED for Server Routing
'urlPathname', // REQUIRED for Server Routing
'apolloInitialState',
'heliumEndpoint',
'appearance',
'documentProps',
'currentUser',
'isProduction',
'queryParams',
'authToken',
'routeParams', // NEW: For dynamic routes like @courseSlug
'assetUrls' // NEW: For asset references
];
Note:
urlParsedandurlPathnamewere already in 2.x templates - no changes needed- Only add
routeParamsif you use dynamic routes (e.g.,@courseSlug.page.tsx) - Only add
assetUrlsif you're using the latest template-base structure - If you started from template-base, these are likely already present
Step 7: Client Routing Configuration (if applicable)
If you're using Client Routing (can be enabled by uncommenting the export below), the passToClient array remains the same as for Server Routing. The only difference is that urlParsed and urlPathname are optional in Client Routing (these values are automatically available), but you can still include them in the array without issues.
To enable Client Routing in renderer/_default.page.client.tsx:
// Uncomment this line to enable Client Routing:
export const clientRouting = true;
// To use Server Routing (default), keep it commented out:
// export const clientRouting = true;
Note: Most applications use Server Routing (the default). Only enable Client Routing if you want instant page transitions without full page reloads.
Step 8: Clean Build and Test
8.1 Clean previous builds
rm -rf dist node_modules package-lock.json
npm install
8.2 Test local development
npm run dev
Visit http://localhost:3000 and verify:
- Pages load correctly
- Navigation works
- GraphQL queries return data
- No console errors
- Translations load properly
8.3 Test production build
npm run build
Verify the build completes without errors and check:
-
dist/client/folder exists with assets -
dist/server/folder exists with SSR code -
dist/client/manifest.jsonexists -
dist/asset-tags.jsonexists
Step 9: Deploy and Test
9.1 Deploy to a sandbox/staging environment first
npm run deploy sandbox
9.2 Verify deployment
- Deployment completes without errors
- Visit your staging instance
- Test all custom pages
- Test navigation between pages
- Check browser console for errors
- Verify GraphQL queries work
9.3 Deploy to production (when ready)
npm run deploy production
Common Migration Issues
Issue 1: Import errors for vite-plugin-ssr
Error:
Cannot find module 'vite-plugin-ssr/server'
Solution:
Replace all vite-plugin-ssr imports with vike:
# Find all occurrences
grep -r "vite-plugin-ssr" . --exclude-dir=node_modules
# Replace (use your editor's find/replace)
vite-plugin-ssr → vike
Issue 2: Build fails with "vike not found"
Error:
Failed to load vike plugin
Solution:
npm install vike@0.4.195
Issue 3: TypeScript errors
Error:
Cannot find type definitions for 'vike'
Solution: Vike includes its own TypeScript definitions. Ensure you're using vike 0.4.195 or higher.
Issue 4: ESM/CJS compatibility errors
Error:
ERR_REQUIRE_ESM: require() of ES Module not supported
Solution:
This should be automatically handled by the new createVikeConfig() function. If you still see this:
- Ensure you're using
createVikeConfig()in your vite.config.ts - Rebuild helium-server:
cd node_modules/@thoughtindustries/helium-server && npm run build - Or reinstall:
rm -rf node_modules && npm install
Issue 5: Deployment fails
Error: Deployment logs show errors or deployment completes but pages don't load
Solution:
- Ensure you're using helium-server 3.0.0 or higher:
npm install @thoughtindustries/helium-server@latest
- Verify your build completed successfully
- Check deployment logs for specific error messages
- Contact TI support with deployment logs if issues persist
Issue 6: Pages show /not-found after deployment
Possible Causes:
- Manifest not generated correctly
- Build artifacts missing
- Deployment error occurred
Solutions:
- Verify build output includes
dist/client/manifest.jsonanddist/asset-tags.json - Check the deployment logs for any errors
- Ensure your build completed successfully before deploying
- Try rebuilding and redeploying
Issue 7: Missing manifest.json or deployment fails
Error:
Missing dist/client/manifest.json
or deployment logs show manifest-related errors.
Cause:
The scripts/ folder is missing from your project, or the build:vite command isn't calling the manifest generation scripts.
Solution: Follow Step 2: Add Required Build Scripts to add the scripts folder and update your build command:
# Add scripts folder
npm pack @thoughtindustries/helium-template@latest
tar -xzf thoughtindustries-helium-template-*.tgz package/scripts
mv package/scripts ./scripts
rm -rf package thoughtindustries-helium-template-*.tgz
Then update package.json:
"build:vite": "vite build && node scripts/generate-manifest.js && node scripts/generate-asset-tags.js"
Breaking Changes Summary
Required Changes
- Update imports:
vite-plugin-ssr→vike - Add build scripts: Copy
scripts/folder and updatebuild:vitecommand - Update vite.config.ts: Use
createVikeConfig()from helium-server - Update dependencies: Install vike, update Vite to 5.x
Optional but Recommended
- passToClient: Ensure
urlParsedandurlPathnameare present for Server Routing (Should already be present in default 2.x applications) - Environment variables: Use
HELIUM_PUBLIC_prefix for client-exposed vars - Clean install: Remove node_modules and package-lock.json before installing
Non-Breaking (Automatic)
- Apollo Client: Automatic cleanup implemented (prevents memory leaks)
- Performance optimization: Improved caching and resource management
- Configuration: Enhanced base settings automatically applied from helium-server
Verification Checklist
After migration, verify these items:
- All imports updated from vite-plugin-ssr to vike
-
scripts/folder added withgenerate-manifest.jsandgenerate-asset-tags.js -
build:vitescript updated to call manifest generation scripts - vite.config.ts uses createVikeConfig()
- Dependencies updated in package.json
- Clean npm install completed
- Local dev server runs (
npm run dev) - Production build succeeds (
npm run build) -
dist/client/manifest.jsongenerated after build -
dist/asset-tags.jsongenerated after build - Deployment to staging succeeds
- All pages load correctly in staging
- Navigation works (both hard navigation and client-side)
- GraphQL queries return data
- No console errors in browser
- Performance is acceptable
- Deployment to production succeeds
- Production instance works correctly
Rollback Plan
If you encounter critical issues during migration:
Quick Rollback
git checkout main # or your previous stable branch
npm install
npm run build
npm run deploy [nickname]
Partial Rollback
If some features work but others don't, you can:
- Keep using 2.x temporarily
- Report issues to TI support
- Wait for hotfix releases
Getting Help
If you encounter issues during migration:
- Check the error message: Most errors include helpful diagnostics
- Review this guide: Ensure all steps were followed
- Check deployment logs: Review any errors from the deployment process
- Contact TI Support: Provide error messages and deployment logs
- GitHub Issues: Check Helium issues for known problems
Additional Resources
- What's New in 3.0 - Detailed overview of all new features and improvements
- Vike Documentation - Official Vike documentation
- Vite 5 Migration Guide - Vite upgrade details
- Helium Framework Docs - Framework overview
- Helium Components - Component documentation
Timeline Recommendation
For a typical Helium application:
- Small projects (1-3 custom pages): 1-2 hours
- Medium projects (5-10 custom pages): 2-4 hours
- Large projects (custom components, complex routing): 4-8 hours
Plan accordingly and test thoroughly in staging before deploying to production.
Last updated: January 2026 Helium version: 3.0.0