DEV Community

Mayuresh Smita Suresh
Mayuresh Smita Suresh Subscriber

Posted on

Building a Todo API with HonoJS, Drizzle ORM & Neon — A Beginner-Friendly Guide

🚀 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
Enter fullscreen mode Exit fullscreen mode

📄 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
Enter fullscreen mode Exit fullscreen mode

▶️ Run the server

npm run dev
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

🗂 Step 2 — Install dependencies

npm install hono @neondatabase/serverless drizzle-orm drizzle-kit
Enter fullscreen mode Exit fullscreen mode

📊 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(),
});
Enter fullscreen mode Exit fullscreen mode

🔌 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 });
Enter fullscreen mode Exit fullscreen mode

🧾 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;
Enter fullscreen mode Exit fullscreen mode

You now have a complete REST API:

  • GET /todos
  • POST /todos
  • PATCH /todos/:id
  • DELETE /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)

Collapse
 
sleewoo profile image
Slee Woo

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...