Software

Choosing PHP, Node or static HTML: how we decide per product

A practical framework for picking a stack per product instead of forcing one everywhere: three questions that decide between static HTML, PHP/Laravel and Node - and the real reasons each Ornova Labs product uses the stack it does.

People sometimes notice that one of our products is built in PHP, another in Node, and our website is just static HTML, and ask whether we couldn't pick one and stick to it. The honest answer is that we choose the stack per product, on purpose. A tool's job decides its technology, not the other way round, and forcing every product into one stack would mean some of them fighting their tools. This is the actual framework we use, and why each of our products ended up where it did.

None of this is about chasing the newest thing. If anything we lean the other way, towards proven, boring technology that we can still run and understand in five years. The framework is just a way of matching a small number of solid choices to the problem in front of us.

There is no default stack

The trap most teams fall into is having a favourite hammer and treating everything as a nail. Pick React for everything and your simple brochure page ships a JavaScript runtime it never needed. Pick a heavy backend for everything and your static content carries a database it never uses. The waste is invisible on a fast laptop and very visible to a user on a phone on a patchy connection. So we start every product from the same neutral question, not "which stack do we like?", but "what does this thing actually have to do?"

Three questions that decide it

Almost every decision comes down to three questions, asked in order.

Mostly content, the samefor everyone? Static HTML Needs database, accounts,forms, server logic? PHP / Laravel Needs a fast JS service,generation or real-time? Node yes yes yes no no
Ask in order. The first "yes" usually picks the stack, and only the work that truly needs server logic gets it.

The order matters, because it stops you over-building. If the honest answer to the first question is yes, you are done, and you have saved yourself an entire backend.

When static HTML wins

If a thing is essentially content, a marketing site, documentation, a blog, a product page, the same for every visitor, static HTML wins outright. It is the fastest to load, the cheapest to host, and the hardest to break, because there is no server logic or database to attack or go wrong. That is exactly why we keep this website on static HTML. "Static" does not have to mean hand-maintained either; we generate these pages from small templates, so the output is plain fast HTML without the tedium people associate with it.

When PHP and Laravel win

The moment a product needs to remember things, accounts, records, forms, files, business rules, the question becomes which mature, data-friendly backend to use, and for us that is very often PHP with Laravel. It is unglamorous and excellent: a database, authentication, file storage, validation and routing all come in the box, hosting is cheap and everywhere, and it has been quietly running serious applications for decades. For a straightforward data-driven application, the kind with projects, entries, users and reports, it lets us build the real thing fast instead of assembling a backend from scratch.

When Node wins

Node earns its place when the job is really about JavaScript: a fast custom service, a generation pipeline, real-time behaviour, or a backend that should share a language and tooling with a heavily interactive JavaScript front end. When a product's hard part lives in the JS ecosystem, fighting that with another language is just friction.

Static HTML Content & docsFastest, cheapest,safest, simplest PHP / Laravel Data appsDB, auth, forms,batteries included Node JS servicesGeneration, real-time,shared toolchain
Three solid tools, three different jobs. The skill is matching, not picking a favourite.

How it played out across our products

Run our catalogue through that framework and the choices explain themselves:

ProductWhat it has to doStack
ornovalabs.comContent, the same for everyoneStatic HTML
Railway PPTAssemble presentations through a fast generation serviceStatic front end + Node service
Railway DPRProjects, daily entries, photos, accounts, reportsLaravel + a JS front end
Rail LDCE PrepQuestion bank, user progress, accountsLaravel + a JS front end
Railway TAForms, records, document and email generationPHP

Notice the pattern: the data-heavy applications lean on PHP and Laravel for the boring, reliable backend work; the one product whose core is a generation service uses Node; and the content site that needs none of that stays static. Each answered the three questions differently, so each landed in a different place.

Mixing stacks on purpose

Running more than one stack is sometimes treated as a failure of discipline. We see it the other way. The cost of a second stack is real, more things to know and maintain, so we do not add one lightly, but the cost of forcing the wrong tool onto a product is usually higher and lasts longer. The discipline is not "one stack forever"; it is "every choice deliberate, and every choice something we can still support". A small, well-understood set of stacks, each used where it fits, beats a single stack stretched somewhere it does not.

The rules we actually follow

  • Start from the job, not the stack. Decide what the product must do before naming a technology.
  • Ask the three questions in order. The first honest "yes" usually picks the tool and saves you over-building.
  • Prefer boring, proven technology. Choose what you can still run and reason about years from now.
  • Don't ship what you don't need. No backend for content, no framework for a brochure.
  • Keep the stack list small but not forced. Add one only when a product genuinely needs it.
  • Optimise for maintenance, not novelty. The exciting choice is rarely the one you thank yourself for later.

There is a well-known essay called Choose Boring Technology that argues a team has only a limited budget for novelty, and should spend it carefully. We agree. Our framework is really just a way of spending that budget where it counts, on the product, not the plumbing, and letting each tool do the job it is genuinely good at.

Frequently asked questions

It depends on what the product has to do. If it is mostly content that is the same for everyone, static HTML is fastest and simplest. If it needs a database, accounts, forms and server logic, a mature backend like PHP with Laravel fits well. If its core is a fast JavaScript service, generation or real-time behaviour, Node is the natural choice. Match the tool to the job rather than to a trend.
For content sites, static HTML is faster to load, cheaper to host and harder to break, because there is no server logic or database behind it. Frameworks earn their weight when there is genuine per-user state to manage; on a brochure or blog they add cost you never recover. Static pages can still be generated from templates, so they are not tedious to maintain.
When the product is data-driven: it needs to store records, authenticate users, handle forms and files, and enforce business rules. Laravel provides the database layer, authentication, storage, validation and routing out of the box, hosting is inexpensive, and it has run serious applications reliably for years, which makes it a strong default for CRUD-style apps.
When the hard part of the product lives in JavaScript: a fast custom service, a generation pipeline, real-time features, or a backend that benefits from sharing a language and toolchain with a heavily interactive JS front end. In those cases using another language just adds friction.
Not if each choice is deliberate and maintainable. A second stack has a real cost in things to know and support, so you should not add one lightly, but forcing the wrong tool onto a product usually costs more and lasts longer. A small set of proven stacks, each used where it fits, is a strength rather than a weakness.
About this article. Written and reviewed by the Ornova Labs Engineering team from direct experience building these tools. Spotted something that needs correcting? Email ornovalabs@gmail.com β€” we update articles when facts change, and the β€œUpdated” date above reflects the last revision.