WendyOS Docs
Guides & TutorialsTypeScript Guides

Simple Web Server

Build a long-running HTTP server on WendyOS using TypeScript

Building a Web Server with Express

Source Code: The complete source code for this example is available at github.com/wendylabsinc/samples/node-typescript/simple-server

Often times you'll want a long-running server where you can make HTTP or WebSocket calls to your WendyOS device. This allows your device to accept incoming requests and respond to them, making it easy to build interactive applications or APIs that can be accessed from other devices on your network.

This guide shows you how to build a web server using Node.js with Express, the most popular and battle-tested framework for Node.js.

Prerequisites

  • Wendy CLI installed on your development machine
  • Node.js 22 or later installed
  • A WendyOS device plugged in over USB or connectable over Wi-Fi

Setting Up Your Project

Initialize the Project

Start from the Wendy Express template:

wendy init simple-server --target wendyos --language node --template simple-api --var APP_ID=simple-server --var PORT=3000 --assistant skip --git-init no
cd simple-server

The template creates package.json, tsconfig.json, src/index.ts, Dockerfile, and wendy.json. The sections below explain the generated server and the pieces you can customize.

Run on WendyOS

wendy run

Wendy will build the app, ask you to select a device if one is not already configured, deploy the app, and print the URL or run output.

Code Breakdown

Generated package.json

Review the generated package.json:

{
  "name": "simple-server",
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsx watch src/index.ts"
  },
  "dependencies": {
    "express": "^4"
  },
  "devDependencies": {
    "@types/express": "^5",
    "@types/node": "^22",
    "typescript": "^5.7",
    "tsx": "^4"
  },
  "engines": {
    "node": ">=22"
  }
}

Generated tsconfig.json

Review the generated tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Generated Web Server

The generated src/index.ts contains the server logic:

import express, { Request, Response } from "express";

const app = express();
const port = 3000;

app.use(express.json());

app.get("/", (_req: Request, res: Response) => {
  res.send("Hello, World!");
});

app.get("/hello/:name", (req: Request, res: Response) => {
  res.send(`Hello, ${req.params.name}!`);
});

interface CreateUserBody {
  username: string;
}

interface User {
  id: number;
  username: string;
}

app.post("/users", (req: Request<{}, User, CreateUserBody>, res: Response) => {
  const user: User = {
    id: 1,
    username: req.body.username,
  };
  res.status(201).json(user);
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

Multiple Routes: This example includes three routes:

  • GET / - Returns "Hello, World!"
  • GET /hello/:name - Returns a personalized greeting
  • POST /users - Creates a new user from JSON body

Generated Dockerfile

The generated project includes a Dockerfile:

# Build stage
FROM node:22-slim AS builder

WORKDIR /app
COPY package*.json ./
RUN npm install

COPY tsconfig.json ./
COPY src ./src
RUN npm run build

# Runtime stage
FROM node:22-slim

WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000

CMD ["node", "dist/index.js"]

Run Again on WendyOS

Deploy your containerized web server to your WendyOS device:

wendy run

Test Your Server on WendyOS

After deploying your server to your WendyOS device, you can test it from your development machine.

You can configure wendy.json with a readiness probe and postStart hook to automatically open your browser when the server is ready:

{
  "readiness": {
    "tcpSocket": { "port": 3000 },
    "timeoutSeconds": 30
  },
  "hooks": {
    "postStart": {
      "cli": "wendy utils open-browser http://${WENDY_HOSTNAME}:3000"
    }
  }
}

Or open your browser manually and navigate to:

http://wendyos-true-probe.local:3000

Replace the hostname: Each WendyOS device has a unique hostname. Replace wendyos-true-probe with your device's actual hostname shown in the CLI output. In addition, don't forget to add the port to the hostname.

You should see the following output:

Hello, World!

This confirms your web server is successfully running on your WendyOS device and accepting requests from your network.

Verifying Deployment

You can verify the server container is running by listing the applications on your device:

wendy device apps list

You should see your containerized web server listed among the running applications.

Learn More

Express is the most popular Node.js web framework. Learn more at https://expressjs.com/

Alternative Frameworks

While this guide covers Express, many other excellent TypeScript web frameworks will work similarly on WendyOS:

  • Fastify: Fast and low overhead web framework
  • Koa: Expressive middleware framework by the Express team
  • Hono: Works on Node.js, Bun, Deno, and edge runtimes
  • NestJS: Progressive framework for building scalable server-side applications

All of these frameworks can be containerized and deployed to WendyOS following the same Docker-based approach outlined in this guide.

Next Steps

Now that you have a basic web server running:

  • Add more routes to handle different endpoints
  • Implement PUT and DELETE routes for a full REST API
  • Add middleware for logging, authentication, and error handling
  • Parse query parameters
  • Implement WebSocket support for real-time communication
  • Connect to databases and external APIs

On this page