Skip to content
Framework: Node.js + ExpressDifficulty: intermediate

Structured Express API

A notes REST API split into router, middleware, and store modules, with logging, error handling, and search.

A step up from the single-file Express starter: routes live in src/routes, cross-cutting concerns (request logging, an HttpError class and a central error handler) in src/middleware.ts, and persistence behind a small store interface so a database can replace the in-memory Map without touching handlers. Supports search and tag filtering through validated query parameters.

  • node
  • express
  • api
  • rest
  • typescript
  • backend

This preview is the template's actual file tree and source code — exactly what is copied into a new project. Codexa does not publish screenshots or mock-ups of templates; run the project to see it rendered.

Files8 files

src/store.ts39 lines
/**
 * In-memory store. Swap this module for a database client (pg, Supabase, Prisma ...) —
 * the router only depends on these four functions.
 */
export type Note = { id: string; title: string; body: string; tags: string[]; createdAt: string; updatedAt: string };

const notes = new Map<string, Note>();
let counter = 1;

function seed() {
  const now = new Date().toISOString();
  const first: Note = { id: String(counter++), title: "Welcome", body: "This API keeps notes in memory. Restarting the server clears them.", tags: ["intro"], createdAt: now, updatedAt: now };
  notes.set(first.id, first);
}
seed();

export function listNotes(filter: { q?: string; tag?: string }) {
  return Array.from(notes.values()).filter((n) => {
    if (filter.tag && !n.tags.includes(filter.tag)) return false;
    if (filter.q) {
      const q = filter.q.toLowerCase();
      return n.title.toLowerCase().includes(q) || n.body.toLowerCase().includes(q);
    }
    return true;
  });
}
export function getNote(id: string) {
  return notes.get(id) ?? null;
}
export function saveNote(input: Omit<Note, "id" | "createdAt" | "updatedAt">, id?: string) {
  const now = new Date().toISOString();
  const existing = id ? notes.get(id) : undefined;
  const note: Note = { id: id ?? String(counter++), ...input, createdAt: existing?.createdAt ?? now, updatedAt: now };
  notes.set(note.id, note);
  return note;
}
export function deleteNote(id: string) {
  return notes.delete(id);
}

Dependencies

Documented from the template's package.json. The runtime has a prebuilt dependency set for Node.js + Express, so installs are fast.

PackageVersion
express^4.21.0
zod^3.24.0
tsx^4.19.0
typescript^5.8.0

How it runs

Framework
Node.js + Express
Dev command
npm run dev
Build command
npm run build
Output directory
dist
Port
3000
Opens at
/api/notes
Difficulty
intermediate

Projects run in an isolated sandbox with a live preview. Read the projects documentation for details on settings, snapshots and deployment.

View all
  • Framework: Vite + React + TypeScriptDifficulty: beginner
    Featured

    React starter

    A clean React + TypeScript + Tailwind single-page app. The default target for AI generation.

    • react
    • typescript
    • tailwind
    • vite
    • spa

    9 files

  • Framework: Node.js + ExpressDifficulty: intermediate

    Express REST API

    A TypeScript Express API with routing, validation, and an in-memory store you can swap for PostgreSQL.

    • node
    • express
    • api
    • typescript
    • backend

    5 files

  • Framework: Vite + React + TypeScriptDifficulty: beginner

    Todo, kanban and notes

    A productivity app with a todo list, a drag-and-drop kanban board, and a notes editor sharing one local dataset.

    • react
    • todo
    • kanban
    • notes
    • productivity

    14 files

Need the raw data? GET /api/v1/templates/node-express-notes-api returns this template with its files.

Build on Structured Express API

Create a free account, start from this template, and ask the AI agent to turn it into your app.