heliumts
v0.4.2
Published
A lightweight full-stack React framework with file-based routing, RPC, and SSG support
Maintainers
Readme
HeliumTS
HeliumTS is a blazing fast 🚀 and opinionated full-stack React + Vite framework designed for simplicity and type safety. It provides seamless RPC communication and file-based routing.
Table of Contents
1. Getting Started
1.1. Installation
The easiest way to get started with HeliumTS is by using the scaffolding tool:
npm create heliumts-app@latest my-helium-appOr (to create in the current directory):
npm create heliumts-app@latest . This command will guide you through setting up a new project with everything configured for you.
If you prefer to set up the project manually, please refer to the Manual Installation Guide.
1.2. Running the Development Server
npx helium dev1.3. Building for Production
npx helium build1.4. Starting the Production Server
npx helium startCheck the working Example APP at: https://github.com/heliobentes/heliumts-example-app
2. Project Structure
A typical HeliumTS project looks like this:
src/
pages/ # Client-side pages (Next.js pages router style)
index.tsx
[id].tsx # Dynamic routes
[...slug].tsx # Catch-all routes
_layout.tsx # Root layout
(protected)/ # Route group (e.g., for auth)
dashboard.tsx
server/ # Server-side logic
tasks.ts # RPC methods for tasks
auth.ts # Auth-related methods
webhooks.ts # Webhook HTTP handlers
workers/ # Background workers
queueConsumer.ts
_middleware.ts # Server middleware
components/ # React components
types/ # Shared types
helium.config.ts # Helium configuration
package.json # NPM package file
vite.config.ts # Vite configuration3. Core Concepts
Using HeliumTS makes it easy to build full-stack applications with minimal boilerplate. It removes the need for separate API routes and REST endpoints by enabling direct RPC calls from the client to server methods using websocket.
No more Axios or fetch calls! Just define your server methods and call them directly from your React components with full type safety.
3.1. RPC (Remote Procedure Calls)
Define server-side functions using defineMethod and call them from the client using useCall or useFetch.
Server (src/server/tasks.ts):
import { defineMethod } from "heliumts/server";
// Getting tasks
export const getTasks = defineMethod(async (args: { status: string }) => {
// Add your own database logic here
return [{ id: 1, name: "Task 1", status: args.status }];
});
// Creating a new task
export const createTask = defineMethod(async (args: { name: string }) => {
// Add your own create task logic
return { id: 2, name: args.name };
});Client (src/pages/tasks.tsx):
import { useFetch, useCall } from "heliumts/client";
import { getTasks, createTask } from "heliumts/server";
export default function TasksPage() {
// Fetch data (auto-runs on mount)
// Data is typed based on server method return type
const { data, isLoading } = useFetch(getTasks, { status: "open" });
// Mutation (callable function)
// The call function is typed based on server method args and return type
const { call: add, isCalling } = useCall(createTask, {
invalidate: [getTasks] // Auto-refresh getTasks after success everywhere it's used
});
return (
<div>
<button onClick={() => add({ name: "New Task" })}>
{isCalling ? "Adding..." : "Add Task"}
</button>
{data?.map(task => <div key={task.id}>{task.name}</div>)}
</div>
);
}3.2. Routing
Helium uses file-based routing in the src/pages directory similar to
Next.js Pages Router.
src/pages/index.tsx->/src/pages/about.tsx->/aboutsrc/pages/users/[id].tsx->/users/:id(dynamic routes)src/pages/_layout.tsx-> Wraps all pagessrc/pages/(protected)/dashboard.tsx->/dashboard(route group)src/pages/[...slug].tsx-> Catch-all route
Link Component:
Helium provides a Link component for client-side navigation:
import { Link } from "heliumts/client";
<Link href="/about">Go to About</Link>useRouter Hook:
Access routing information and navigation methods:
import { useRouter } from "heliumts/client";
function MyComponent() {
const router = useRouter();
// Access current route
console.log(router.path); // "/users/123"
console.log(router.params.id); // "123"
console.log(router.searchParams); // URLSearchParams
console.log(router.status); // 200 | 404
// Navigate programmatically
router.push("/dashboard");
router.replace("/login");
// Listen to route changes
router.on("navigation", (event) => {
console.log(`Navigated to ${event.to}`);
});
}See Routing Documentation for detailed information including dynamic routes, layouts, and navigation.
3.3. Custom HTTP Handlers
For cases when you need to listen to webhooks or create REST endpoints, use defineHTTPRequest.
Useful for integrating with third-party services like Stripe, GitHub, and Auth clients.
3.3.1. Stripe Webhook Example
Server (src/server/webhooks.ts):
import { defineHTTPRequest } from "heliumts/server";
export const stripeWebhook = defineHTTPRequest("POST", "/webhooks/stripe", async (req, ctx) => {
const body = await req.json();
// Handle webhook
return { received: true };
});3.3.2. Better Auth Example
Server (src/server/auth.ts):
import { defineHTTPRequest } from "heliumts/server";
export const authHandler = defineHTTPRequest("ALL", "/auth/:provider", async (req, ctx) => {
// Call the better-auth handler directly
return auth.handler(await req.toWebRequest());
});*toWebRequest() converts Helium's Request to a standard web Request object.
3.4. Background Workers
Create long-running background processes using defineWorker. Perfect for queue consumers, scheduled jobs, and background tasks.
Server (src/server/workers/queueConsumer.ts):
import { defineWorker } from "heliumts/server";
export const queueConsumer = defineWorker(async (ctx) => {
console.log("Queue consumer started");
while (true) {
const job = await queue.pop();
if (job) {
await processJob(job);
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}, { name: 'queueConsumer' });When the server starts:
Starting worker 'queueConsumer'Workers support auto-restart, configurable restart delays, and max restart attempts. See Workers Documentation for queue consumers, scheduled tasks, and more.
3.5. Middleware
You can define a middleware to intercept requests to the server.
Server (src/server/_middleware.ts):
import { middleware } from "heliumts/server";
export default middleware(async (ctx, next) => {
console.log("Request received");
// Add your database connection or auth logic here
return next();
});3.6. helium.config.ts
Helium's configuration file allows you to customize server settings including RPC encoding, compression, security, and proxy configuration.
import type { HeliumConfig } from "heliumts/server";
const config: HeliumConfig = {
trustProxyDepth: 1, // Trust 1 proxy level (e.g., Vercel)
rpc: {
encoding: "msgpack", // or "json"
compression: {
enabled: true,
threshold: 1024,
},
security: {
maxConnectionsPerIP: 10,
maxMessagesPerWindow: 100,
rateLimitWindowMs: 60000,
tokenValidityMs: 30000,
},
},
};
export default config;See Configuration Documentation for detailed options.
3.7. Static Site Generation (SSG)
HeliumTS supports Static Site Generation (SSG) through pre-rendering pages at build time.
Add a "use ssg"; directive at the top of your page component to enable SSG:
SSG page: (src/pages/about.tsx)
"use ssg";
import React from "react";
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>This page is statically generated at build time.</p>
</div>
);
}During build, Helium validates SSG pages and generates optimized static HTML files.
See SSG Documentation for detailed information including limitations, hybrid rendering, and best practices.
4.CLI Reference
helium dev: Starts Vite in development mode.helium build:- Builds the client using Vite.
- Scans
src/serverfor exports. - Bundles the server using esbuild.
- Transpiles
helium.config.tstodist/helium.config.js(if present).
helium start: Runs the bundled server (dist/server.js).
5. More Documentation
Getting Started
- Manual Installation - Step-by-step guide to setting up a HeliumTS project manually
Core Features
- Data Fetching - useFetch and useCall hooks for data fetching and mutations
- Routing & useRouter - File-based routing, dynamic routes, navigation, and the useRouter hook
- Configuration - Configure RPC encoding, compression, security, and proxy settings
- Static Site Generation - Pre-render pages at build time for better performance
- Route Groups - Organize routes with shared layouts without affecting URLs
- Background Workers - Long-running background processes for queues, scheduled tasks, and more
Deployment & Advanced
- Context API - Access request metadata including client IPs and headers
- Proxy Configuration - Configure IP detection for rate limiting behind proxies
- HTTP Handlers & Webhooks - Create custom HTTP endpoints for webhooks and REST APIs
- Production Deployment - Deploy to production platforms and platform compatibility
⚠️ Hosting Note: Helium requires a platform that supports persistent Node.js servers (e.g., Digital Ocean, Railway, Render). Serverless platforms like Vercel and Netlify are not fully compatible due to WebSocket limitations. See Production Deployment for details.
6. Contributing
Contributions are welcome! Please read the contributing guide for details.
7. License
This project is licensed under the MIT License. See the LICENSE file for details.
