Concept project, not commissioned

Northlight booking

Concept project, not commissioned. A booking site for an imaginary photo studio, built to show that two people can never take the same slot.

Kind
Concept project, not commissioned
Year
2026
Our role
Design and build
Stack
Node.js 22, SQLite, JavaScript, CSS
The Northlight Studio booking page with a portrait session, Saturday 17 October and 12:00 selected, and a booking summary on the right.

What this is

Northlight Studio is not a real business. We made it to build one thing properly: a booking flow with a server that tells the truth. Pick a session, a day and a time, and the slot is yours or it is not. No email is sent, and the page says so at the top.

The full booking page: session choice, a two week day grid, time frames and a booking summary.
The whole flow on one page. Taken frames are struck through.

Numbers we measured

Automated tests passing
20
node --test, unit and HTTP
Bookings that win a five way race
1 of 5
race test, same slot, same moment
axe violations
0
axe-core, 390 and 1440 px
Lighthouse, mobile and desktop
100 / 100
Layout shift 0

How a slot is protected

Checking that a slot is free and then saving it are two steps. If they are separate, two visitors can both pass the check. We run both inside one write transaction, so the second visitor sees the first booking and gets a clear “taken” answer.

src/db.js

create({ service, date, start, end, name, email, note }) {
  db.exec('BEGIN IMMEDIATE');
  try {
    const clash = busyStmt.all(date).some((b) => overlaps(start, end, b.start, b.end));
    if (clash) {
      db.exec('ROLLBACK');
      return null;
    }
    const reference = code(6);
    const token = randomBytes(16).toString('hex');
    insertStmt.run(reference, token, service, date, start, end, name, email, note);
    db.exec('COMMIT');
    return { reference, token };
  } catch (error) {
    db.exec('ROLLBACK');
    throw error;
  }
}
The check and the insert happen inside one transaction.

Decisions

Database

The choice
The SQLite module that ships with Node 22.
What we rejected
A third party SQLite package.
Why
The project has no dependencies to install or update. The cost is that the built in module is still marked experimental, so a real deployment would pin the Node version.

Studio time

The choice
Every slot is calculated in the studio's own time zone, on the server.
What we rejected
Using the visitor's clock.
Why
A visitor in another country must not see a slot that has already passed in the studio, or book one outside opening hours.

Confirmation

The choice
A reference code and a private cancel link on screen. No email.
What we rejected
Sending a confirmation email.
Why
This is a concept with no real studio behind it. Sending mail to real addresses for a fake business would be wrong.

A bug we found and fixed

The first Lighthouse run on a phone reported a layout shift of 0.23. The service cards and the day grid were drawn after the data arrived, so the page jumped. We wrote the service cards into the HTML and gave the day grid a fixed size. The shift is now 0.

Also covered

  • Sessions Tuesday to Saturday, 30 minute steps, up to 30 days ahead, at least an hour of notice.
  • A hidden field that catches simple bots, and a limit on booking and login attempts.
  • A small admin page with a password, to see and cancel bookings.
  • A content security policy that allows only the site’s own files.

Tell us what you want to build.

Every project is scoped from your tasks and priced after we read your brief.

Start a project
  1. 01Send the brief A few fields. Ten minutes is enough.
  2. 02Get a written quote Scope, price and a delivery date.
  3. 03Watch it get built A private preview link while we work.