Deno
Build secure, type-safe APIs with Igniter.js and Deno, the modern JavaScript runtime built for security and productivity.
Deno is a modern JavaScript runtime that prioritizes security, developer experience, and web standards. When combined with Igniter.js, you get a secure-by-default environment with native TypeScript support, built-in testing, and automatic code formatting—all without configuration.
This guide shows you how to build production-ready APIs with Deno and Igniter.js. You'll experience Deno's security model with granular permissions, standard library utilities, and native TypeScript execution, all while maintaining Igniter.js's type-safe controllers and automatic API documentation.
Secure by Default
Deno + Igniter.js provides security-first development. Deno requires explicit permissions for file system, network, and environment access—perfect for production deployments.
Quick Start
The fastest way to start is using the official CLI with Deno's native TypeScript support:
npx @igniter-js/cli@latest initpnpm dlx @igniter-js/cli@latest inityarn dlx @igniter-js/cli@latest initbunx @igniter-js/cli@latest initYour API runs at http://localhost:8000/api/v1, and interactive docs at http://localhost:8000/api/v1/docs 🚀
Manual Setup
Complete Deno Setup Guide
Prerequisites
Before you begin, ensure you have:
- Deno 1.40+ (install here)
- Basic knowledge of TypeScript
Initialize Deno Project
Create a new directory and initialize with deno.json:
{
"tasks": {
"dev": "deno run --allow-net --allow-env --allow-read --watch src/index.ts",
"start": "deno run --allow-net --allow-env --allow-read src/index.ts"
},
"compilerOptions": {
"lib": ["deno.window"],
"strict": true
},
"imports": {
"@/": "./src/",
"@igniter-js/core": "npm:@igniter-js/core@latest",
"zod": "npm:zod@latest"
}
}Deno's import map allows you to use npm packages seamlessly with native Deno modules.
Define Application Context
The context defines dependencies available throughout your API. Create src/igniter.context.ts:
/**
* Application Context Type
* Defines what dependencies are available to all API handlers
*/
export interface AppContext {
// Add your dependencies here, e.g.:
// db: Database
// cache: KvStore
}
/**
* Context Factory
* Creates the context instance passed to handlers
*/
export function createIgniterAppContext(): AppContext {
return {
// Initialize dependencies here
}
}Initialize Igniter.js
Create the main Igniter instance. Create src/igniter.ts:
import { Igniter } from '@igniter-js/core'
import { createIgniterAppContext } from './igniter.context.ts'
export const igniter = Igniter
.context(createIgniterAppContext())
.config({
baseURL: Deno.env.get('IGNITER_API_URL') || 'http://localhost:8000',
basePATH: Deno.env.get('IGNITER_API_BASE_PATH') || '/api/v1',
})
.docs({
info: {
title: 'My Deno API',
version: '1.0.0',
description: 'Secure API built with Deno and Igniter.js',
}
})
.create()Note: Deno uses Deno.env.get() for environment variables with explicit --allow-env permission.
Create Your First Controller
Controllers group related endpoints. Create src/features/example/controllers/example.controller.ts:
import { igniter } from '@/igniter.ts'
export const exampleController = igniter.controller({
name: 'Example',
path: '/example',
actions: {
hello: igniter.query({
path: '/hello',
handler: async ({ response }) => {
return response.success({
message: 'Hello from Igniter.js with Deno! 🦕',
timestamp: new Date().toISOString(),
runtime: 'Deno',
version: Deno.version.deno
})
},
}),
},
})Create barrel export at src/features/example/index.ts:
export * from './controllers/example.controller.ts'This creates GET /api/v1/example/hello with fully typed responses.
Create Application Router
The router assembles all controllers. Create src/igniter.router.ts:
import { igniter } from './igniter.ts'
import { exampleController } from './features/example/index.ts'
export const AppRouter = igniter.router({
controllers: {
example: exampleController
}
})
export type AppRouterType = typeof AppRouterSet Up Deno Server
Deno has a built-in HTTP server based on web standards. Create src/index.ts:
import { serve } from 'https://deno.land/std@0.203.0/http/server.ts'
import { AppRouter } from './igniter.router.ts'
const handler = (req: Request) => {
const url = new URL(req.url)
const IGNITER_API_BASE_PATH = Deno.env.get('IGNITER_API_BASE_PATH') || '/api/v1'
// Route to Igniter.js
if (url.pathname.startsWith(IGNITER_API_BASE_PATH)) {
return AppRouter.handler(req)
}
return new Response('Not Found', { status: 404 })
}
const port = 8000
serve(handler, { port })
console.log(`🚀 Server running at http://localhost:${port}/`)Deno's serve function uses the standard Request and Response APIs—no framework needed!
Step 7: Run with Permissions
Deno requires explicit permissions. Run your server:
# Development with auto-reload
deno task dev
# Or run directly
deno run --allow-net --allow-env --allow-read --watch src/index.tsPermissions explained:
--allow-net: Network access for HTTP server--allow-env: Read environment variables--allow-read: Read files (for static assets, configs)--watch: Auto-reload on file changes
Deno-Specific Features
Native TypeScript
Deno runs TypeScript natively—no build step required. File extensions are mandatory:
// Always include .ts extension
import { igniter } from './igniter.ts'
import type { User } from './types.ts'Environment Variables
Create .env file and load with --env flag:
IGNITER_API_BASE_PATH=/api/v1
IGNITER_API_URL=http://localhost:8000
DATABASE_URL=postgresql://localhost/mydbAccess via Deno.env.get():
const dbUrl = Deno.env.get('DATABASE_URL')Or use the --env flag:
deno run --env --allow-net --allow-env src/index.tsDeno KV (Built-in Database)
Deno includes a built-in key-value database:
export async function createIgniterAppContext() {
const kv = await Deno.openKv()
return {
db: kv
}
}Use it in controllers:
const result = await context.db.get(['users', userId])
await context.db.set(['users', userId], userData)Standard Library
Deno's standard library provides utilities without npm:
// File system
import { ensureDir } from 'https://deno.land/std@0.203.0/fs/mod.ts'
// HTTP server
import { serve } from 'https://deno.land/std@0.203.0/http/server.ts'
// Testing
import { assertEquals } from 'https://deno.land/std@0.203.0/assert/mod.ts'Type-Safe Client
Create a type-safe client for consuming your API. Create src/igniter.client.ts:
import { createIgniterClient } from '@igniter-js/core/client'
import type { AppRouterType } from './igniter.router.ts'
export const api = createIgniterClient<AppRouterType>({
baseURL: Deno.env.get('IGNITER_API_URL') || 'http://localhost:8000',
basePATH: Deno.env.get('IGNITER_API_BASE_PATH') || '/api/v1',
router: () => {
// Dynamic import for Deno
return import('./igniter.router.ts').then(m => m.AppRouter)
},
})
export type ApiClient = typeof apiUse it anywhere:
// Fully typed, secure by default
const { message, version } = await api.example.hello.query()Testing with Deno
Deno has built-in testing—no additional packages needed:
import { assertEquals } from 'https://deno.land/std@0.203.0/assert/mod.ts'
import { api } from '@/igniter.client.ts'
Deno.test('Example controller returns hello message', async () => {
const result = await api.example.hello.query()
assertEquals(result.runtime, 'Deno')
assertEquals(typeof result.version, 'string')
})Run tests:
deno test --allow-net --allow-envIgniter Studio (API Playground)
Igniter.js includes an interactive API playground called Igniter Studio. It's automatically available at /api/v1/docs when you configure the .docs() method.
To access it:
- Start your dev server:
deno task dev - Navigate to
http://localhost:8000/api/v1/docs - You'll see an interactive interface where you can:
- Browse all API endpoints
- View request/response schemas
- Test endpoints directly
- See auto-generated examples
The playground updates automatically as you add endpoints.
Production Deployment
Deno Deploy
Deploy to Deno's edge network with zero configuration:
# Install Deno Deploy CLI
deno install --allow-all --no-check -r -f https://deno.land/x/deploy/deployctl.ts
# Deploy your project
deployctl deploy --project=my-api src/index.tsDocker
Create a Dockerfile:
FROM denoland/deno:1.40.0
WORKDIR /app
COPY . .
RUN deno cache src/index.ts
EXPOSE 8000
CMD ["deno", "run", "--allow-net", "--allow-env", "--allow-read", "src/index.ts"]Project Structure
Here's the recommended structure: