Getting Started with Hono JS and Drizzle ORM
December 16, 2024

Getting Started with Hono JS and Drizzle ORM

This brief summary is best used as companion documentation to support the Hono JS and Drizzle ORM introductory video tutorials.

We create a set of API routes to support operating the user object, which is a sqlite database. We use drizzle ORM to interact with the database.


  • connect – Fast, lightweight, and built based on web standards. Supports any JavaScript runtime.
  • Drizzle ORM – You can define and manage database schemas in TypeScript, access data in SQL-like or relational ways, and leverage opt-in tools to improve your developer experience.


Installation and setup

Run the command to get started with a basic Hono application, we will focus on the Nodejs setup.

npm create hono@latest
Enter full screen mode

Exit full screen mode

Your terminal output should resemble the following.

aaronksaunders@Aarons-iMac LIVE % npm create hono@latest
Need to install the following packages:
create-hono@0.14.3
Ok to proceed? (y) y

> npx
> create-hono

create-hono version 0.14.3
? Target directory my-hono-1
? Which template do you want to use? nodejs
? Do you want to install project dependencies? yes
? Which package manager do you want to use? npm
✔ Cloning the template
✔ Installing project dependencies
🎉 Copied project files
Get started with: cd my-hono-1
Enter full screen mode

Exit full screen mode

The minimal code for the hono server is at index.ts

import { serve } from "@hono/node-server";
import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => {
  return c.text("Hello Hono!");
});

// set port
const port = 3000;
console.log(`Server is running on http://localhost:${port}`);

// serve app
serve({
  fetch: app.fetch,
  port,
});
Enter full screen mode

Exit full screen mode

Now to test the build, change to directory and run the command below.

npm run dev
Enter full screen mode

Exit full screen mode

The server should be running on localhost:3000if you access it in a web browser, you should receive a response from the server.

Hello Hono!
Enter full screen mode

Exit full screen mode


Added Drizzle and SQLite

Useful links

Execute the following command in the terminal

npm i drizzle-orm better-sqlite3 dotenv
npm i -D drizzle-kit tsx
Enter full screen mode

Exit full screen mode

  • better-sqlite-3 is the sqlite version we use in our application – dotenv is used to read environment files
  • drizzle-kit is a set of utilities that support drizzle orm integration

create .env document

DATABASE_URL=./db.sqlite
Enter full screen mode

Exit full screen mode

Create a drizzle directory, which is the location where the migration files will be generated.

create /src/db/schema.ts and add the following information

import { sql } from "drizzle-orm";
import { int, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";

export const usersTable = sqliteTable(
  "users_table",
  {
    id: int().primaryKey({ autoIncrement: true }),
    name: text().notNull(),
    age: int().notNull(),
    email: text().notNull().unique(),
    createdAt: text()
      .notNull()
      .default(sql`CURRENT_TIMESTAMP`),
    updatedAt: text()
      .notNull()
      .default(sql`CURRENT_TIMESTAMP`),
  },
  (table) => [uniqueIndex("email_idx").on(table.email)]
);

export type User = typeof usersTable.$inferSelect;
export type InsertUser = typeof usersTable.$inferInsert;
Enter full screen mode

Exit full screen mode

We are building a table and exporting some types that can be used when interacting with the output of a query or constructing objects that need to be queried.

create /src/db/index.ts Used to manage database execution instances created by drizzle orm.

// src/db/index.ts
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "./schema.js";
import "dotenv/config";

const sqlite = new Database(process.env.DATABASE_URL ?? "sqlite.db");

export const db = drizzle(sqlite, { schema });
Enter full screen mode

Exit full screen mode

create drizzle.config.ts In the project root directory

import "dotenv/config";
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  out: "./drizzle",
  schema: "./src/db/schema.ts",
  dialect: "sqlite",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});
Enter full screen mode

Exit full screen mode

Add script to package.json Generate migrations and apply them to the repository

 "db:generate": "drizzle-kit generate",
 "db:migrate": "drizzle-kit migrate"
Enter full screen mode

Exit full screen mode

Run the script to build the repository and push the migration. The terminal output should be similar to the following output.

aaronksaunders@Aarons-iMac my-hono-1 % npm run db:generate                    

> db:generate
> drizzle-kit generate

No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/aaronksaunders/dev/LIVE/my-hono-1/drizzle.config.ts'
1 tables
users_table 6 columns 2 indexes 0 fks

[✓] Your SQL migration file ➜ drizzle/0000_wakeful_greymalkin.sql 🚀
aaronksaunders@Aarons-iMac my-hono-1 % npm run db:migrate 

> db:migrate
> drizzle-kit migrate

No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/aaronksaunders/dev/LIVE/my-hono-1/drizzle.config.ts'
[✓] migrations applied successfully!%                                                         
aaronksaunders@Aarons-iMac my-hono-1 % 
Enter full screen mode

Exit full screen mode

Use drizzle kit studio to add some users to the database.





npx drizzle-kit studio 
Enter full screen mode

Exit full screen mode

Add a new route to query users in the database

import { db } from "./db/index.js";
import { Hono } from "hono";
import { usersTable } from "./db/schema.js";
import { eq } from "drizzle-orm";
const usersRoute = new Hono();

// Get all users
usersRoute.get("/", async (c) => {
  const allUsers = await db.query.usersTable.findMany();
  return c.json(allUsers);
});

// Get a user by id, be sure to note the conversion of
// the id from string back to a number
usersRoute.get("/:id", async (c) => {
  const { id } = c.req.param();
  const userResp = await db.query.usersTable.findFirst({
    where: eq(usersTable.id, Number(id)),
  });
  return c.json(userResp);
});

// Create a user
usersRoute.post("/", async (c) => {
  const { name, email, age } = await c.req.json();
  const newUserResp = await db.insert(usersTable).values({ name, email, age });
  return c.json(newUserResp);
});

export default usersRoute;
Enter full screen mode

Exit full screen mode

Adjustment index.ts Include a new set of routes





import { serve } from "@hono/node-server";
import { Hono } from "hono";
import usersRoute from "./users-route.js";

const app = new Hono();

app.get("/", (c) => {
  return c.text("Hello Hono!");
});

// Use the users routes
app.route("/users", usersRoute);

const port = 3000;
console.log(`Server is running on http://localhost:${port}`);

serve({
  fetch: app.fetch,
  port,
});
Enter full screen mode

Exit full screen mode

Use tools like postman or thunderbolt VSCode Extension to test the API


source code


video

2024-12-16 16:30:22

Leave a Reply

Your email address will not be published. Required fields are marked *