Static site generation feels normal now.
Nobody finds it strange when a website page is built ahead of time and served from a CDN as a file. In fact, for many types of websites, that is exactly what we prefer. It is faster, simpler, cheaper, and usually more predictable.
But when it comes to JSON APIs, we often behave differently.
Even when the response is already known.
Even when the data changes slowly.
Even when the endpoint is mostly just returning structured content.
We still put a runtime behind it almost by default.
That kept bothering me.
I kept seeing APIs that were doing almost nothing at request time. A docs navigation endpoint. A changelog feed. A public product catalog. Release metadata. A feature list. Public config. AI-readable content.
The response was not really being “computed” in any meaningful way on every request. The backend was mostly just standing there, breathing behind the JSON.
That felt weird to me.
At some point, the idea became very simple:
What if some APIs could be generated ahead of time, just like static pages?
That is where StatikAPI came from.
The simplest way to explain it is:
Static export, but for APIs.
The problem I kept noticing
In a lot of projects, the API is not actually as “live” as we make it look.
Sometimes it is just structured content.
Sometimes it is a list of products, docs pages, team members, feature flags, metadata, or public configuration.
Sometimes the backend exists mostly to take some source data and return it as JSON.
And yes, runtime APIs are absolutely needed for many things.
Payments need a runtime.
User-specific dashboards need a runtime.
Mutation-heavy systems need a runtime.
Anything that depends on live request-time logic probably needs a runtime.
But many endpoints are not like that.
Many endpoints are read-heavy. The data changes only when the source changes. The response shape is predictable. The work can happen earlier.
And yet we still keep a server or function alive for every request.
That means more moving parts than we need.
More latency than we need.
More things to deploy, secure, observe, debug, and pay for.
Not because the problem is always complex.
Sometimes the delivery model is just heavier than the actual problem.
That is the part I wanted to explore.
The simple idea
StatikAPI generates JSON API outputs ahead of time.
Instead of rendering HTML ahead of time, it generates JSON ahead of time.
Instead of running a function on every request, it writes the response to disk as a static JSON file.
Instead of asking a backend to recompute the same response again and again, it builds the response once and lets you serve the output directly.
The source of truth is route files inside src-api/.
Those route files map to URLs, and the build turns them into static JSON endpoints inside api-out/.
For example:
export default {
project: 'StatikAPI',
example: 'basic',
timestamp: new Date().toISOString(),
message: 'Hello from example/basic!',
};
That is the basic shape.
A route file exports JSON-serializable data. StatikAPI builds it and writes the output as a JSON endpoint.
So instead of thinking:
“I need an API server for this.”
You can ask:
“Can this response be generated before the request even happens?”
If the answer is yes, then maybe that endpoint does not need to be alive all the time.
Maybe it just needs a build step.
What StatikAPI does today
The current OSS version is intentionally direct.
I did not want the first version to be clever. I wanted the model to be obvious:
src-api/in, JSON out.
Right now, StatikAPI can:
- turn filesystem route modules into static JSON endpoints
- write the generated output into
api-out/ - generate a manifest at
.statikapi/manifest.json - run a local dev flow with watch/rebuild behavior
- provide a preview UI at
/_ui/ - scaffold a new project through
create-statikapi
The routing model is filesystem-based, so the structure feels familiar:
src-api/index.js -> /
src-api/about.js -> /about
src-api/users/[id].js -> /users/:id
src-api/docs/[...slug].js -> /docs/*slug
For dynamic routes, paths() tells StatikAPI which concrete outputs to generate.
export async function paths() {
return ['1', '2', '3', '4', '5', '6'];
}
export async function data({ params }) {
return { id: params.id, extra: 'value' };
}
That is the part that makes the idea click for me.
The route still feels like an API route.
But the final result is not a runtime response.
It is a prebuilt JSON output.
Why this matters
I built StatikAPI for the kind of data that does not need to be recomputed on every request.
Things like:
- docs and content endpoints
- changelog feeds
- public metadata APIs
- product catalogs
- generated config or manifest endpoints
- feature lists
- read-heavy data that changes on a schedule
- build-time fetched data from another API or service
- AI-readable content endpoints
For these use cases, static JSON can make a lot of sense.
The request becomes simpler.
It is not “run code, fetch data, transform data, return JSON.”
It is just:
read the already prepared JSON and serve it.
That gives you fewer runtime dependencies.
It can reduce latency.
It can make deployment simpler.
It can make the cost structure lighter.
And honestly, it just makes the system easier to reason about.
Predictability is underrated.
When an endpoint is prebuilt, you know exactly where it came from.
You know what file generated it.
You know when it changed.
You know what the output is before traffic hits it.
A request becomes a read.
Not a tiny execution environment.
What this is not for
I do not think every API should become static.
That would be a silly claim.
StatikAPI is not for highly personalized request-time logic.
It is not for payment flows.
It is not for realtime mutation-heavy systems.
It is not a replacement for every backend.
If the data needs to be computed per user, per request, or per moment, then a runtime is still the right answer.
But if the data is mostly read-only, predictable, and only changes when the source changes, then maybe the runtime is just extra weight.
That is the line I care about.
I wanted something boring, predictable, and fast for the class of APIs that can be prepared ahead of time.
Not everything needs to be alive all the time.
Why I kept pushing on this
I have been thinking a lot about static-first and edge-first systems.
Not because “edge” sounds cool.
But because many products become expensive or complicated not only because their logic is complex, but because the delivery model is heavier than it needs to be.
A lot of data is already known before the request comes in.
A lot of content is prepared earlier.
A lot of public JSON is closer to static output than live computation.
So I kept coming back to the same question:
If the response can be known earlier, why are we computing it later?
StatikAPI came from that pressure point.
Not as a grand theory.
More like a practical reaction to a pattern I kept seeing again and again.
There are plenty of places where the shape of the problem is closer to static output than runtime logic.
Docs.
Metadata.
Public feeds.
Product data.
Generated content.
AI-readable structured data.
I wanted a tool that treated that seriously.
Why I open-sourced it first
I chose open source first because this idea needs real feedback.
I do not want to hide the core behind a hosted product and ask people to trust the idea before they can inspect it.
I want developers to read the files, understand the route model, try the build flow, and tell me where it breaks.
Maybe the mental model makes sense.
Maybe it needs better examples.
Maybe the source integrations need to grow.
Maybe some parts are still confusing.
That is exactly the kind of feedback I want.
Open source keeps the conversation honest.
It also lets developers use the core idea without waiting for a hosted platform.
That felt important to me.
Try it
The quickest way to start is with the scaffold:
pnpm dlx create-statikapi my-api
cd my-api
pnpm dev
You can also use:
yarn dlx create-statikapi my-api
or:
npx create-statikapi my-api
The examples in the repo show the current shape:
-
example/basicshows a simple static endpoint -
example/dynamicshows dynamic and catch-all routes -
example/showcaseincludes TypeScript and build-time remote fetches
The basic idea is still the same:
Create API-like route files.
Build them.
Get static JSON output.
What I want feedback on
I would genuinely love feedback on the idea.
Especially around questions like:
- Does this mental model make sense?
- What kind of APIs would you generate statically?
- What source integrations would make this more useful?
- Where would this fit in your real projects?
- What would stop you from using something like this?
If the idea feels useful, I would really appreciate a star, comment, issue, or even criticism.
GitHub: https://github.com/zonayedpca/statikapi
Closing
I am not claiming every API should become static.
I am saying some APIs probably should not need a runtime at all.
That is the space I am exploring with StatikAPI.
And instead of keeping the idea in my head forever, I wanted to put it out in the open and see what other developers think.
Top comments (0)