Skip to main content

Quick Start

Create a New Project

npx @evjs/create-app my-app
cd my-app && npm install

Both arguments are optional — if omitted, the CLI prompts interactively.

Available Templates

TemplateDescription
basicRouting + server functions
mpaMulti-page application setup
api-routesProgrammatic REST API routes via createRoute()
complex-routingParams, search, root layout, loaders, nested paths
with-tailwindTailwind CSS via PostCSS
with-trpctRPC interop example
with-sqliteFull-stack CRUD with SQLite
custom-ws-transportCustom WebSocket transport
plugin-authoringPlugin lifecycle and bundler hook examples

Development

ev dev

Your browser opens to http://localhost:3000 with Hot Module Replacement. Server functions in "use server" modules are auto-discovered from explicit app/page/server roots.

Production Build

ev build

Project Structure

my-app/
├── .gitignore # Ignores generated evjs type files
├── index.html # HTML template (must have <div id="app">)
├── ev.config.ts # Optional config
├── src/
│ ├── layout/
│ │ └── index.tsx # Optional SPA root layout
│ ├── pages/ # Page routes
│ │ ├── index.tsx # /
│ │ └── users/$id.tsx # /users/$id
│ └── api/ # Server-only modules
│ ├── users.server.ts # "use server" functions
│ └── health.routes.ts
├── package.json
└── tsconfig.json

Pages

// src/pages/users/$id.tsx
import { usePageParams, useQuery } from "@evjs/client";
import { getUser } from "../../api/users.server";

export default function UserPage() {
const { id } = usePageParams();
const { data } = useQuery(getUser, id);
return <main>{data?.name}</main>;
}

When src/pages exists and the project does not declare explicit app, pages, or remote config, evjs automatically builds an SPA from the file tree. The generated routing glue stays inside the framework; SPA mode only writes src/evjs-route-types.d.ts for TypeScript and scaffolded apps ignore it by default.

SPA root layout discovery is optional. Use src/layout/index.tsx beside the route directory, set routing.layout to another module path, or set routing.layout: false when the app should not have a framework root layout.

MPA Mode

Use the same src/pages files for an MPA and switch the routing mode:

// ev.config.ts
import { defineConfig } from "@evjs/ev";

export default defineConfig({
routing: {
mode: "mpa",
},
});

Each page is emitted as its own HTML document and client entry without SPA router setup. The layout/index.tsx convention is SPA-only and lives beside the page route directory using that exact path; MPA pages compose shared wrappers as normal components and do not accept routing.layout.

Packages

PackagePurpose
@evjs/evFramework API, config, plugins, build orchestration, and deployment helpers
@evjs/cliThin CLI wrapper (ev dev, ev build, ev inspect) with the default bundler
@evjs/create-appProject scaffolding (npx @evjs/create-app)
@evjs/clientBrowser runtime APIs for page hooks, navigation, transport, remotes, and RSC
@evjs/serverHono/fetch server runtime APIs for server functions, routes, rendering, and deployment

Manifest schemas, build tools, page runtime, and shell internals are internal modules under the public packages above. Application config/build code imports from @evjs/ev; runtime code imports from @evjs/client, @evjs/server, or @evjs/server/react. Use @evjs/cli and @evjs/create-app as tools, not application imports. Bundler adapters such as @evjs/bundler-utoopack and shared contract modules such as @evjs/shared are only for custom framework tooling or adapter work.

Declare @evjs/client when application source or generated SPA entries need the browser runtime. Declare @evjs/server when the app uses server functions, server routes, framework rendering, or deployment runtime wrappers.

Required Dependencies

{
"dependencies": {
"@evjs/client": "<same version>",
"@evjs/ev": "<same version>",
"@evjs/server": "<same version>",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@evjs/cli": "<same version>",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^6.0.2"
}
}
important

Keep all @evjs/* packages in your app on the same version. Most applications only need @evjs/ev plus @evjs/cli; if you add direct runtime or adapter packages, upgrade them together.

Key Rules

  • Config file: ev.config.ts (not evjs.config.ts)
  • Import defineConfig from @evjs/ev, not from @evjs/server
  • HTML must have <div id="app"> for the render target
  • Do NOT add "type": "module" to your project's package.json — the server bundle uses CJS format
  • Prefer src/pages as the route source of truth.
  • Keep src/evjs-route-types.d.ts generated and ignored; do not import it.
  • Use routing.mode: "mpa" for independent pages without a client router.