Custom development
Some problems do not fit a website. When the work is a tool, an integration or a process that should not be done by hand any more, we build that instead.
Small, senior, and honest about scope. If an existing product solves your problem, we will say so rather than bill you to rebuild it.
Register
The kinds of work we take on
A useful way to describe bespoke software is by the problem it removes. These are the shapes that come up most often, and the thing we usually end up building.
| The problem | What we build |
|---|---|
| The same manual task, every day, by a person who is too senior for it | An internal tool with the steps encoded once: a form, a queue, a clear audit trail, and permissions that match how the team actually works. |
| Two systems that will not talk to each other | An integration that owns the mapping between them, retries safely when one side is down, and tells you when something needs a human. |
| The business running on a spreadsheet nobody dares to touch | A small web application with a real data model behind it, so two people can work at once and last quarter's numbers cannot be overwritten by accident. |
| A report somebody assembles by hand every week | A scheduled job that gathers the data, checks it, and delivers the report to the people who need it, with a record of every run. |
| A customer workflow bolted onto a marketing site until it broke | A proper application at its own address, sharing the site's design system so it still feels like one company. |
| Something nobody can price because nobody has scoped it | A short discovery step: the smallest working version defined in writing, with the parts we would not build listed just as plainly. |
Judgement
How we decide what to build
- The smallest thing that works, first. A narrow tool in production teaches you more in two weeks than a complete specification teaches you in a quarter, and it can be extended once you know which parts matter.
- Boring technology on purpose. We choose the proven option over the interesting one. Bespoke software is judged on the day somebody has to change it, not on the day it launches.
- Get the data model right early. Interfaces are cheap to redraw and data is expensive to restructure, so the shape of the data is settled before the screens are.
- Buy before build. If a licensed product covers your case, the honest recommendation is to use it. We would rather build the small piece that connects it than charge you to reinvent it.
- Design for the second developer. Readable code, documented setup, tests that explain the intent. The measure of the work is whether somebody else can safely change it.
Stack
The technology we actually use
Naming it is part of being honest about scope. A technical buyer should be able to tell in one screen whether we are the right studio, and a non-technical one should be able to hand this section to their own developer and get a straight answer.
TypeScript, end to end
Astro, plain HTML and CSS, React where an app genuinely needs it
Node and Cloudflare Workers
Postgres-compatible databases, versioned SQL migrations
Cloudflare Pages, Workers, object storage, scheduled triggers
Playwright, Vitest, static types, automated accessibility audits
- One language across the whole system. TypeScript for the interface, the API, the scheduled jobs and the tests, with types checked on every change. One language means one toolchain and one review standard, and no translation layer between the browser and the service behind it.
- Rendering chosen per job. Content compiles to static HTML. An interface that genuinely needs client state gets a component framework, scoped to the part of the screen that needs it, rather than a framework wrapped around content that never changes.
- A relational database, not a document soup. A Postgres-compatible database with a typed query layer, and schema changes that are reviewed, applied in order and reversible. Nobody edits a production schema by hand.
- Serverless by default, because there is no server to forget about. Code runs on Cloudflare's edge platform, with object storage for files and scheduled workers for anything that has to happen on a timer. No machine of yours to patch at midnight and no capacity to guess at.
- Integrations over documented interfaces. Other systems are reached through their APIs and webhooks with retries, idempotency and a record of every call. Where a provider offers no API, a scheduled file or data feed is the deliberate fallback, never screen scraping something that will break next quarter.
- Environments and secrets as configuration, never as folklore. Infrastructure is declared in the repository, credentials live in a secret store and reach the running service as environment values, and a new machine is running the project the same afternoon.
- Your stack, when you already have one. If your team maintains something reasonable, the right answer is usually to work inside it rather than to introduce a second way of doing everything. And if what you have is genuinely the problem, you will hear that too.
Standards
The same engineering floor as the websites
The floor does not move between the two service lines, because an internal tool is used for years by people who cannot choose a different one. A repository you own with its full history, automated checks that stop a red deploy, one-command releases that revert in one step, accessible interfaces (staff deserve the standard customers get), secrets kept out of code, and accounts that can be transferred to your own organization whenever you want them. It is set out in detail under corporate websites rather than repeated here.
Two things carry more weight in software than on a site, and they are worth naming separately.
The data outlives the code
Interfaces get replaced; the records stay. So schema changes are migrations in the repository, applied in order and reversible, backups are the platform's job rather than a script somebody wrote once, and your data can be exported in a form you could load somewhere else entirely.
A running system has to be observable
Anything that happens with nobody watching leaves a record: what ran, when, what it touched and what it failed on. A scheduled job that quietly stops working tells us, instead of being discovered a month later by the person who wondered where their report went.
Scope
Where we stop
Being clear about the edges is part of being trustworthy. We are a small senior team, so we take on work we can do well and we say no to work we cannot.
We do not resell licensed platforms, we do not staff a project we are not building, and we will not quote a number for a problem that has not been scoped. Where a piece of the work belongs to a specialist, we will tell you that plainly rather than learn it at your expense.
The technical edges are just as specific:
- Web applications yes, native mobile apps no. We build for the browser, including an interface a phone can install to its home screen. An app written in Swift or Kotlin and shipped through the app stores is a different discipline and we do not pretend otherwise.
- Using a model yes, data science no. We will call a hosted model or an existing service from your application and build the interface and the plumbing around it. Training models, statistical analysis and warehouse-scale data pipelines are not what we do.
- Managed platforms yes, your own servers no. We deploy to managed edge and serverless platforms. If the work has to run in your data centre, on machines you administer, or on an operating system somebody has to keep patched, we are the wrong studio and you will hear it on the first call.
- Certified regimes need a specialist beside us. We apply real security engineering as a matter of course, but a formal audit against a named regime is a specialism we do not sell. If your project needs one, we say so before you sign anything, not afterwards.
- Not our disciplines at all. Games, embedded firmware, desktop applications, and anything whose value would be a licence we resold rather than work we did.
After handover
Who keeps it running afterwards
Bespoke software is not finished when it launches. It gets used, and then it needs changing. Who does that belongs in the scope at the start, not in an awkward email six months later.
We stay on, if that suits you
Changes after launch follow the same loop as the build: a branch, a preview, the full set of checks, and a deploy that reverts in one step. There is no support contract you have to sign for the system to keep working, because no part of it is rented from us.
Being a small senior team has a cost and we would rather state it: we do not run a 24-hour on-call rotation and we do not sell a guaranteed response measured in minutes. If what you are building genuinely needs that, tell us early and we will say honestly whether we can meet it.
Or your own people take it over
The repository, the tests, the documented setup and the deploy are yours, and a competent developer can pick the project up without us. That is what designing for the second developer, above, is actually for.
The platform helps here as well. A static site and a serverless service have no server to patch and no operating system to keep current, so what remains is dependency and platform updates: a scheduled, reviewable change rather than an emergency.
You do not need a specification to start. Reach us via the contact form or at sales@wwi.dev and describe the work in plain language.