Express is the most popular way to build a website in Node.js, and it's happy doing two jobs at once: serving your static pages and answering API requests with JSON. This guide gets that running on Falix with a template, then walks the code so you can extend it.
| At a glance | |
|---|---|
| You need | A server running the Node.js application |
| Plan | Any plan |
| Time | Fifteen minutes |
If Node is new to you, read Node.js on Falix first — it explains the index.js entry file and automatic npm install that this guide builds on.
Step 1 — Deploy the template
Use the Express Website + API template on this page. It writes an index.js, a package.json with Express as a dependency, and a public/ folder with a sample page. Because a package.json now exists, Express installs itself automatically the first time the server starts — you don't run npm by hand.
Press Start. The console runs npm install, then your app, and prints Listening on port … — the line that flips the server to online. Open your server's address (from the Network page) in a browser to see the sample page, and click through to /api/hello to see the JSON route.
Step 2 — Read the starter code
Here's the index.js the template installs. It's the whole app:
const express = require('express');
const path = require('node:path');
const app = express();
app.use(express.json());
// Everything in public/ is served as-is: index.html, CSS, images...
app.use(express.static(path.join(__dirname, 'public')));
// ...and this is an API route. Add your own below it.
app.get('/api/hello', (req, res) => {
res.json({ message: 'Hello from your Falix API!' });
});
const PORT = process.env.SERVER_PORT || 8080;
app.listen(PORT, '0.0.0.0', () => {
console.log(`Listening on port ${PORT}`);
});
Two ideas carry the whole file. express.static(...) hands every file in public/ straight to the browser, so your HTML/CSS/JS live there just like a static site. And app.get('/api/hello', ...) defines a route that runs code and returns JSON. The listen call reads SERVER_PORT and binds 0.0.0.0 — the two rules from Your first web app — so leave it as-is.
Step 3 — Add your own route
Say you want a live visit counter. Add this above the app.listen(...) call:
let visits = 0;
app.get('/api/visits', (req, res) => {
visits++;
res.json({ visits });
});
Save, then restart the server. Open /api/visits and refresh a few times — the number climbs.
🎯 Good to know: It's stored in memory, so it resets to 0 whenever the server restarts. To make it survive restarts, save it to a file or a database — see Store your app's data for the file approach, or Add a database.
💡 Tip: That edit-then-restart loop is how you develop here: change
index.js, restart, refresh.
Serving a single-page app, and seeing requests
If public/ holds a built single-page app (React, Vue, Svelte…), its client-side router needs every unknown path to return index.html rather than a 404. Add a catch-all after express.static and every API route, so it only handles whatever nothing else matched:
// Keep this LAST — after express.static and all your API routes.
app.use((req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
To watch traffic arrive, drop a one-line logger in near the top, right after app.use(express.json()):
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
Every request now prints a line in the Console. For richer logs with status codes and response times, install morgan from the Packages page and use app.use(require('morgan')('dev')) instead.
Step 4 — Add a package
Need something off npm — say axios for outbound HTTP calls? Open the Packages page in your server menu, type axios in the Install package panel, and press Install. It updates your package.json for you and runs the real npm install; watch it finish under Tasks. Then restart so your app loads the new module. The same page flags outdated and insecure packages, so it's worth a look even when nothing's broken.
Troubleshooting
- Page won't load / connection refused — a port or bind-address problem, not a code one. The
listencall must useSERVER_PORTand0.0.0.0; see I can't reach my app. Cannot find module 'express'(or any package) — it isn't installed. Open the Packages page and install it, then restart. The console also offers a one-click install when it spots this error.- API route returns broken JSON or a 500 — read the console; the stack trace names the file and line. Make sure every response path ends in
res.json(...)orres.send(...)exactly once.