Installation
Requirements
Section titled “Requirements”- Node.js 24.13 or later.
- TypeScript, with standard JavaScript decorators.
- Express 5, which you install alongside viga.
Install viga
Section titled “Install viga”viga runs on top of Express, so you install it yourself alongside the framework. As development dependencies, add TypeScript, tsx to run the app while you code, and the Express and Node.js types.
pnpm add viga expresspnpm add -D typescript tsx @types/express @types/nodenpm install viga expressnpm install -D typescript tsx @types/express @types/nodeyarn add viga expressyarn add -D typescript tsx @types/express @types/nodebun add viga expressbun add -d typescript tsx @types/express @types/nodeConfigure TypeScript
Section titled “Configure TypeScript”Create a tsconfig.json at the project root:
{ "compilerOptions": { "target": "ES2024", "lib": ["ES2024", "ESNext.Decorators"], "module": "nodenext", "moduleResolution": "nodenext", "rewriteRelativeImportExtensions": true, "strict": true, "skipLibCheck": true, "outDir": "dist", "rootDir": "src" }, "include": ["src"]}ESNext.Decoratorsadds the types for standard decorators.- With
rewriteRelativeImportExtensions, imports between your own files use their real extension, likeimport { BooksService } from './books.service.ts', andtscchanges it to.jswhen compiling. Packages are imported by name, without an extension:import { createApp } from 'viga'.
Configure the project
Section titled “Configure the project”viga is an ES module package, so your project must be one too. In your package.json, add "type": "module" and the scripts to develop, build and start:
{ "type": "module", "scripts": { "dev": "tsx watch src/main.ts", "build": "tsc", "start": "node dist/main.js" }}devruns the app withtsxand restarts it every time you save a file.buildcompiles the project to JavaScript in thedistfolder.startruns the compiled version, the one you’ll use in production.
Why you need to compile
Section titled “Why you need to compile”Node.js can run TypeScript files by stripping the types, but it doesn’t understand decorators yet: node src/main.ts fails at the first @. That’s why, while you develop, tsx transforms the decorators on the fly, and for production tsc generates JavaScript that Node.js runs directly.
Importing without extensions
Section titled “Importing without extensions”The configuration above uses ES modules, the standard Node.js format, which requires the extension in imports between your files. If you’d rather write them without an extension, as in NestJS, you have two alternatives.
With a bundler. tsc only checks types, and a bundler like esbuild generates the JavaScript, resolving the imports for you. Install esbuild as a development dependency and change these options in your tsconfig.json:
{ "compilerOptions": { "module": "preserve", "moduleResolution": "bundler", "noEmit": true }}And the build script in your package.json:
{ "scripts": { "build": "tsc && esbuild src/main.ts --bundle --platform=node --format=esm --packages=external --outfile=dist/main.js" }}With CommonJS, the format NestJS uses. Remove "type": "module" from your package.json, and tsc will generate require(...), which doesn’t need an extension. This works because Node.js 24 can load ES module packages like viga with require. CommonJS doesn’t allow await outside a function, so the startup goes inside one:
import { createApp } from 'viga';import { AppModule } from './app.module';
async function bootstrap() { const app = createApp({ rootModule: AppModule, globalPrefix: '/api' }).enableShutdownHooks(); await app.listen();}
void bootstrap();Keep in mind that CommonJS is the older Node.js format and that some new packages are already published only as ES modules.
Packages for the optional modules
Section titled “Packages for the optional modules”The core and most optional modules don’t need anything else. Some depend on packages you install only if you use them:
| Module | Packages it needs |
|---|---|
viga/validation |
A Standard Schema compatible library, like zod, valibot or arktype |
viga/drizzle |
drizzle-orm and pg, and @types/pg as a development dependency |
viga/websocket |
ws, if you use the default adapter |
You install them the same way as viga, with your package manager.