🚀 Getting Started with HonoJS — Routing + Drizzle + Neon Todo API
HonoJS is an ultrafast, lightweight web framework designed for building APIs across Node.js, Bun, Deno, and Edge runtimes like Cloudflare Workers and Vercel Edge Functions.
In this tutorial, we’ll:
- Learn simple routing in Hono
- Build a Todo API using Drizzle ORM + Neon PostgreSQL
- Discuss why this stack is great for modern backends
- Give a shout-out to two real-world apps built using Hono:
⚡ Why HonoJS?
Hono stands out because it’s:
- 🔥 Extremely fast & lightweight
- 🌍 Multi-runtime compatible
- 🧠 TypeScript-first
- 🧩 Middleware-friendly
It gives you power similar to Express — but optimized for edge & serverless environments.
✨ Simple Routing Example in Hono
📦 Create a new project
npm create hono@latest
# or
pnpm create hono@latest
yarn create hono@latest
📄 Basic routing (index.ts)
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('👋 Hello from Hono!'))
app.get('/api/hello', (c) => {
return c.json({ message: 'This is a JSON response!' })
})
export default app
▶️ Run the server
npm run dev
You now have a fully working API with clean, type-safe routing.
🧩 Building a Todo API with Hono + Drizzle + Neon
We’ll combine:
- 🛠 Hono → API router
- 🐘 Neon → Serverless PostgreSQL
- 📦 Drizzle ORM → Type-safe database layer
🧠 Step 1 — Set up Neon & env
Create a Neon database and copy your connection string:
DATABASE_URL="postgres://your-connection-string"
🗂 Step 2 — Install dependencies
npm install hono @neondatabase/serverless drizzle-orm drizzle-kit
📊 Step 3 — Define Drizzle schema (src/db/schema.ts)
import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';
export const todos = pgTable('todos', {
id: serial('id').primaryKey(),
content: text('content').notNull(),
completed: boolean('completed').default(false).notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
🔌 Step 4 — Connect database (src/db/index.ts)
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import * as schema from './schema';
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });
🧾 Step 5 — Create CRUD API routes (src/app.ts)
import { Hono } from 'hono';
import { db } from './db';
import { todos } from './db/schema';
const app = new Hono();
// Get all todos
app.get('/todos', async (c) => {
const all = await db.select().from(todos);
return c.json(all);
});
// Create todo
app.post('/todos', async (c) => {
const { content } = await c.req.json();
const newTodo = await db.insert(todos).values({ content }).returning();
return c.json(newTodo);
});
// Mark completed
app.patch('/todos/:id', async (c) => {
const id = Number(c.req.param('id'));
const updated = await db
.update(todos)
.set({ completed: true })
.where(todos.id.eq(id))
.returning();
return c.json(updated);
});
// Delete todo
app.delete('/todos/:id', async (c) => {
const id = Number(c.req.param('id'));
await db.delete(todos).where(todos.id.eq(id));
return c.text('Deleted');
});
export default app;
You now have a complete REST API:
GET /todosPOST /todosPATCH /todos/:idDELETE /todos/:id
💡 Why This Stack Works So Well
- ⚡ Hono = fast & edge-ready
- 🧠 Drizzle = type-safe SQL
- 🐘 Neon = scalable serverless Postgres
- 🧩 Perfect for microservices & APIs
🙌 Real-World Projects Using Hono
I’ve successfully used Hono in production on:
👉 MoneySense.ai — smart financial insights
👉 MenuGo.live — modern digital restaurant platform
Both rely on Hono-powered backends for reliability and performance.
🚀 Next Steps
Consider adding:
- 🔒 Auth (JWT / Clerk / Lucia)
- 🧪 Zod validation
- 📊 Analytics & logging
- 🌐 Frontend UI for the Todo API
🎯 Final Thoughts
HonoJS is a fantastic framework if you want:
- Edge-ready performance
- Clean routing
- Strong TypeScript support
- Easy integration with serverless tools like Neon
Whether you’re prototyping or scaling production systems like MoneySense.ai and MenuGo.live, Hono is a powerful and modern backend.
Top comments (1)
Nice! Seems Hono gets some traction latelly, would be interesting to compare to Koa some day.
Your setup looks solid, with a bit of automation would work even smoother; i mean automated routing like here - kosmojs.dev/routing/intro.html - and automated middleware like here - kosmojs.dev/api-server/use-middlew...