#Getting Started
This guide takes you from zero to a running Alepha server in under five minutes. No Webpack, no Babel, no ESLint configuration.
#Prerequisites
You need one of the following:
- Node.js 22+ (recommended for beginners)
- Bun 1.1+
#Create a Project
npx alepha@latest init my-app
This creates a my-app directory with:
package.jsonwith Alepha as a dependencytsconfig.jsonconfigured for TypeScriptalepha.config.tswith documented build optionsbiome.jsonfor formatting and lintingsrc/main.server.tsas the entry file
Dependencies are installed automatically.
#Init Flags
You can scaffold more structure with flags:
npx alepha@latest init my-app --api # Add API module (src/api/)
npx alepha@latest init my-app --api --react # Add API + React frontend (src/web/)
npx alepha@latest init my-app --api --react --admin # Full stack with admin panel
npx alepha@latest init my-app --test # Include Vitest test directory
npx alepha@latest init my-app --pm=bun # Use Bun as package manager
Flag cascading: --admin implies --auth, which implies --api and --ui, which implies --react.
For this guide, we will start with the simplest possible app.
#Your First Server
After running init, enter the project:
cd my-app
Open the entry file. For a minimal project (no flags), it looks like this:
1import { Alepha, run } from "alepha";2 3const alepha = Alepha.create();4 5run(alepha);
This starts an empty server. Let us add a route. Replace the file contents with:
1import { run } from "alepha"; 2import { $route } from "alepha/server"; 3 4class App { 5 hello = $route({ 6 path: "/", 7 handler: () => "Hello, Alepha!", 8 }); 9}10 11run(App);
That $route call is a Primitive -- a factory function that registers an HTTP endpoint
directly on your class. No separate router file, no middleware chain.
run(App) creates an Alepha container, registers App, starts the server, and handles
signal trapping (SIGINT, SIGTERM) for graceful shutdown.
#Run in Development Mode
npm run dev
You should see:
[02:10:43.013] INFO <alepha.core.Alepha>: Starting App...
[02:10:43.013] INFO <alepha.core.Alepha>: App is now ready [0ms]
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
Open http://localhost:5173 in your browser. You will see "Hello, Alepha!".
Development mode gives you:
- Hot Module Replacement (HMR) -- change code, server updates instantly.
- TypeScript support -- no build step required.
- Pretty logs -- readable, structured output.
#Add a Typed API Endpoint
$route is low-level. For real APIs, use $action -- it adds schema validation, automatic
OpenAPI documentation, and type-safe client calls.
1import { t, run, $inject } from "alepha"; 2import { $action } from "alepha/server"; 3import { DateTimeProvider } from "alepha/datetime"; 4 5class App { 6 dateTimeProvider = $inject(DateTimeProvider); 7 8 hello = $action({ 9 path: "/hello",10 schema: {11 response: t.object({12 message: t.text(),13 serverTime: t.datetime(),14 }),15 },16 handler: () => ({17 message: "Hello from Alepha",18 // consider using `dateTimeProvider.nowISOString()` instead of `new Date().toISOString()`19 // for better testability and consistency across runtimes20 serverTime: this.dateTimeProvider.nowISOString(),21 }),22 });23}24 25run(App);
Key differences from $route:
- All
$actionpaths are automatically prefixed with/api. This endpoint serves atGET /api/hello. - The
schema.responsevalidates the return value and generates OpenAPI documentation. - If a
schema.bodyis provided, the method defaults toPOST. - The response is type-checked at compile time.
Save the file. HMR reloads the server. Visit http://localhost:5173/api/hello.
#Build for Production
When you are ready to deploy:
npm run build
This produces a dist/ folder with an optimized, self-contained bundle.
Run it locally to verify:
node dist
Or with Bun:
bun dist
App starts up just like in development mode, but without HMR and with better performance.
In production, default port is 3000 instead of 5173 to avoid conflicts with development servers.
SERVER_PORTenvironment variable can override this.
#Build Targets
Alepha adapts the build output based on where you deploy:
npm run build -- --target=docker # Generates a Dockerfile in dist/
npm run build -- --target=vercel # Adapts output for Vercel serverless
npm run build -- --target=cloudflare # Adapts output for Cloudflare Workers
npm run build -- --runtime=bun # Optimizes for Bun runtime
# or with alepha
npx alepha build
Build targets and runtime can also be set in alepha.config.ts:
1import { defineConfig } from "alepha/cli/config";2 3export default defineConfig({4 build: {5 target: "docker", // will produce a Dockerfile with Node.js base image6 runtime: "node",7 },8});
#Project Structure
With --api and --react flags, alepha init scaffolds this structure:
my-app/
alepha.config.ts # Build and entry point configuration
package.json
tsconfig.json
biome.json
src/
main.server.ts # Server entry point
main.browser.ts # Browser entry point (React apps)
main.css # Global styles (React apps)
api/
index.ts # API module definition
controllers/
HelloController.ts # Example $action endpoint
schemas/
helloResponseSchema.ts
web/
index.ts # Web module definition
AppRouter.ts # $page routes
components/
Home.tsx # Example React component
Entry file conventions:
src/main.ts-- server-only apps (API)src/main.server.ts-- server entry when a browser entry also existssrc/main.browser.ts-- browser entry for React apps