Home Documentation Templates Examples Showcase GitHub ↗
Theme

Deployment architecture

Nift in a serverless stack

Nift is a build-time frontend layer, not an application server. That makes it unusually easy to combine with serverless backends: generate HTML, CSS and browser JavaScript ahead of time, put those files on static hosting or a CDN, and let small functions handle only the requests that genuinely need runtime compute.

The boundary is simple.

Nift owns static composition and build-time data. Your serverless platform owns authentication callbacks, APIs, webhooks, database mutations, payments, email, background work and other runtime behavior. Browser JavaScript is ordinary web JavaScript, so it can call any HTTP API.

The basic architecture

                    build time
content + JSON + templates ── Nift ──► static HTML/CSS/JS
                                           │
                                           ▼
                                      CDN / static host
                                           │
                                           ▼
                                         browser
                                           │ fetch()
                    ┌──────────────────────┼──────────────────────┐
                    ▼                      ▼                      ▼
             serverless API          auth / database         third-party API
             or edge function        / storage service       / webhook

This split can keep most requests out of application compute entirely. A product page, documentation page, dashboard shell or marketing page can be a static Nift output; only an action such as signing in, loading private account data or submitting an order needs a function.

A small frontend calling a function

<form id="contact">
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>

<script type="module">
document.querySelector('#contact').addEventListener('submit', async event => {
  event.preventDefault();

  const body = Object.fromEntries(new FormData(event.currentTarget));
  const response = await fetch('/api/contact', {
    method: 'POST',
    headers: {'content-type': 'application/json'},
    body: JSON.stringify(body)
  });

  if (!response.ok) throw new Error('Request failed');
});
</script>

Nothing about that code needs a Nift-specific server API. The endpoint can be Lambda, Azure Functions, Cloud Run functions, Supabase Edge Functions, Vercel Functions, Netlify Functions, a conventional backend, or something you write five years from now.

AWS: S3/CloudFront + API Gateway + Lambda

A natural AWS arrangement is to deploy Nift's generated site to S3 behind CloudFront, then route dynamic API requests through API Gateway to AWS Lambda. Lambda runs event-driven code without you provisioning servers and automatically handles the underlying compute infrastructure.

Nift build
   │
   ├──► S3 ──► CloudFront ──► /, /docs, /pricing, assets...
   │
   └────────────────────────► deployment pipeline

browser ──► API Gateway ──► Lambda ──► DynamoDB / S3 / SES / other APIs

A Lambda might accept a contact form, create a checkout session, generate a signed S3 upload URL, process an S3 event, or expose private application data:

export const handler = async event => {
  const body = JSON.parse(event.body ?? '{}');

  // Validate input, write to a service, send mail, etc.
  return {
    statusCode: 200,
    headers: {'content-type': 'application/json'},
    body: JSON.stringify({ok: true, email: body.email})
  };
};

For a content-heavy site, the useful property is that Lambda is not involved in serving every page. Nift already rendered those pages. Lambda is reserved for runtime work.

Azure: Static Web Apps or Storage/CDN + Azure Functions

On Azure, generated Nift output can live in static hosting while Azure Functions provides event-driven compute. Functions can expose HTTP APIs but can also react to schedules, queues, database changes and other events.

import { app, HttpRequest, HttpResponseInit } from '@azure/functions';

app.http('profile', {
  methods: ['GET'],
  authLevel: 'anonymous',
  handler: async (request: HttpRequest): Promise<HttpResponseInit> => {
    return {jsonBody: {name: 'Ada', plan: 'pro'}};
  }
});

A Nift-generated account shell can request that endpoint after authentication. The public document remains static; private data remains runtime data.

Google Cloud: static hosting/CDN + Cloud Run functions

Google Cloud's Cloud Run functions are single-purpose functions that can respond to HTTP requests or CloudEvents without you managing the runtime environment. A Nift frontend can be deployed independently and call those functions through ordinary HTTP.

const functions = require('@google-cloud/functions-framework');

functions.http('status', (req, res) => {
  res.json({ok: true, generatedFrontend: 'nift'});
});

The same pattern works for event processing: a generated frontend uploads through a controlled API, while a function reacts to an object/storage event and performs processing asynchronously.

Supabase: Nift + Postgres/Auth/Storage + Edge Functions

Supabase is particularly complementary because Nift does not try to become a database, authentication system or backend framework. Supabase can provide Postgres, Auth and Storage, while Edge Functions handle privileged or custom server-side operations.

Deno.serve(async request => {
  const {orderId} = await request.json();

  // Perform privileged validation/database/payment work here.
  return Response.json({accepted: true, orderId});
});

Supabase Edge Functions are TypeScript-first and globally distributed. Good uses beside a Nift frontend include webhook receivers, transactional email, payment integration, protected database operations and calls to APIs whose secrets must never reach browser JavaScript.

Nift static UI
   ├──► Supabase Auth
   ├──► permitted Postgres operations via client + RLS
   ├──► Supabase Storage
   └──► Edge Function ──► privileged DB/API/payment operation

Vercel: static Nift output + Functions

Vercel Functions run server-side code without managing servers and can sit behind API routes while Nift continues to produce the frontend. You do not need to adopt Next.js merely to use a serverless endpoint.

Nift route contracts and Vercel routes are different concepts.

A Nift route contract is a build-time application relationship such as routes.users.list → /api/users. Vercel routing rules describe what its deployment should do when an incoming request matches. They can complement each other, but Nift does not redefine Vercel's routing model.

// api/hello.ts
export default {
  fetch(request: Request) {
    return Response.json({message: 'Hello from the server'});
  }
};

A useful repository shape is:

content/
templates/
assets/
api/
  contact.ts
  checkout.ts
.nift/
package.json

Your build command runs Nift; Vercel handles the server-side function directory according to its platform configuration.

Netlify: static deployment + Netlify Functions

Netlify follows the same clean split. Functions can be JavaScript, TypeScript or Go and can act as HTTP endpoints, event handlers, scheduled functions or background work.

// netlify/functions/contact.ts
export default async (request: Request) => {
  const message = await request.json();

  // Validate and deliver message.
  return Response.json({received: true});
};
Nift ──► generated static deployment
browser ──► /.netlify/functions/contact
                         │
                         └──► email/database/API

This is a good example of why Nift does not need a plugin for every hosting provider: the integration boundary is files plus normal HTTP.

GitHub Pages: static frontend, functions somewhere else

GitHub Pages is static hosting, so it does not itself become the serverless backend. That is not a limitation on the Nift architecture. Deploy the generated site to GitHub Pages and call a separately hosted API.

GitHub repository
   │
   ├── GitHub Actions ──► nift build ──► GitHub Pages
   │
   └── function source ──► AWS / Azure / GCP / Supabase / other host

GitHub Pages frontend ── HTTPS ──► serverless API

For public APIs this can be extremely simple. For authenticated APIs, configure the function's CORS policy and authentication model for the Pages origin. Secrets belong in the function/platform configuration, never in generated frontend files.

Build-time data versus request-time data

A useful design question is not “static or dynamic?” but when does this value need to change?

Changes when the site is deployed?
    └── @json + @for + @if + Nift build

Changes for each visitor/request?
    └── browser JavaScript + API/function

Requires a secret or privileged credential?
    └── function/backend

Needs database mutation?
    └── function or carefully secured backend service

Mostly static shell with one interactive area?
    └── Nift page + ordinary JS or a React/Vue/Svelte island

A product catalogue can, for example, be generated from JSON at build time while current stock is fetched from a function. Documentation can be entirely static while search analytics or feedback submission is serverless. A dashboard shell can be generated once while account-specific cards load after sign-in.

Serverless functions are not template functions

Nift's @input, @json, @for and @if execute while building files. Lambda/Functions/Edge Functions execute later in response to requests or events. Keeping those phases separate is valuable: Nift can stay deterministic and fast, while runtime code gets the security, scaling and event model it needs.

Where build scripts fit

Nift deliberately does not execute arbitrary shell commands from templates. Compose the deployment pipeline outside the template language instead:

{
  "scripts": {
    "build:frontend": "nift build",
    "test:functions": "node --test functions/tests/*.test.js",
    "build": "npm run test:functions && npm run build:frontend"
  }
}

That boundary is more powerful than teaching Nift about every cloud CLI. Terraform, Pulumi, AWS SAM/CDK, Azure tooling, gcloud, Supabase CLI, Vercel CLI, Netlify CLI and GitHub Actions can evolve independently while Nift remains a small build tool.

Security boundary

Anything emitted by Nift is ultimately downloadable by a visitor. Never put database passwords, service-role keys, payment secrets or private API credentials into templates, JSON data that becomes public output, or browser JavaScript. Put secrets in the serverless platform's secret/environment configuration and let the function expose only the operation the browser actually needs.

The larger point

Serverless is a strong example of Nift's “glue, not the universe” philosophy. Nift does not need an AWS plugin, an Azure plugin, a Supabase runtime or a proprietary function API. It generates standards-based frontend files; serverless platforms expose standards-based HTTP endpoints and events. The whole web-development ecosystem remains available on both sides of that boundary.