APINode.js

Express REST API

Minimal Express 5 JSON API with CORS, a health check and in-memory CRUD routes; uses Node's built-in --watch.

Open in builder →

7 steps

Shell

Shown with defaults: npm, pip, Node LTS, Python 3.12 and the template's default add-ons.

  1. 1. Install and select Node.js with nvm

    runtime

    nvm lets you install several Node.js versions side by side and switch per project. `nvm use` activates it for this shell.

    bash
    nvm install --ltsnvm use --lts
    Expected result
    `node -v` prints the selected version.
    Verify
    node -v && npm -v
    OS notes
    macOS/Linux/WSL: install nvm with `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash`, then reopen the terminal. Windows: use nvm-windows (github.com/coreybutler/nvm-windows) from an elevated terminal, or fnm.
  2. 2. Create the project folder

    template

    Create an empty folder for the project and move into it. All following commands run inside it.

    bash
    mkdir nvx-apicd nvx-api
    Expected result
    You are inside ./nvx-api
    Verify
    pwd
  3. 3. Initialise package.json

    template

    Create a package.json with default values so you can add dependencies and scripts.

    bash
    npm init -y
    Expected result
    A package.json file exists.
    Verify
    node -e "console.log(require('./package.json').name)"
  4. 4. Install Express and CORS

    template

    express handles routing; cors lets browsers on other origins call the API.

    bash
    npm install express cors
    Expected result
    express and cors in dependencies.
    Verify
    npm ls express
  5. 5. Configure ES modules and scripts

    template

    npm pkg set edits package.json safely: enable import syntax and add dev/start scripts (node --watch restarts on save).

    bash
    npm pkg set type=module 'scripts.dev=node --watch src/index.js' 'scripts.start=node src/index.js'
    Expected result
    package.json has "type": "module" and dev/start scripts.
    Verify
    npm pkg get type scripts
  6. 6. Write the API server

    template

    Routes: GET /health, and CRUD on /api/todos.

    Files written by this step: src/index.js
    src/index.js
    import express from "express";
    import cors from "cors";
    
    export const app = express();
    app.use(cors());
    app.use(express.json());
    
    let nextId = 1;
    const todos = [];
    
    app.get("/health", (_req, res) => res.json({ ok: true, service: "nvx-api" }));
    
    app.get("/api/todos", (_req, res) => res.json(todos));
    
    app.post("/api/todos", (req, res) => {
      const title = String(req.body?.title ?? "").trim();
      if (!title) return res.status(400).json({ error: "title is required" });
      const todo = { id: nextId++, title, done: false };
      todos.push(todo);
      res.status(201).json(todo);
    });
    
    app.patch("/api/todos/:id", (req, res) => {
      const todo = todos.find((t) => t.id === Number(req.params.id));
      if (!todo) return res.status(404).json({ error: "not found" });
      if (typeof req.body?.done === "boolean") todo.done = req.body.done;
      res.json(todo);
    });
    
    app.delete("/api/todos/:id", (req, res) => {
      const index = todos.findIndex((t) => t.id === Number(req.params.id));
      if (index === -1) return res.status(404).json({ error: "not found" });
      todos.splice(index, 1);
      res.status(204).end();
    });
    
    if (process.env.NODE_ENV !== "test") {
      const port = Number(process.env.PORT) || 3000;
      app.listen(port, () => console.log("API ready on http://localhost:" + port));
    }
    
    Expected result
    src/index.js exists.
    Verify
    node --check src/index.js
  7. 7. Run the API

    templaterun manually · dev server

    Starts the server on port 3000 and restarts on file changes.

    bash
    npm run dev
    Expected result
    Console prints: API ready on http://localhost:3000
    Verify
    curl http://localhost:3000/health