From Tooling Standards to Shared Server Abstractions

For years, web developers patched the platform's gaps with bundlers, polyfills, and build transforms. The ecosystem has since consolidated around common preferences: TypeScript for typing and Vite for development tooling. On top of those foundations, frameworks such as SolidStart, Nuxt, Remix, and Analog have grown full ecosystems. Vite and TypeScript act as tooling primitives — reusable pieces that let framework authors build faster instead of reinventing base infrastructure.

With those needs settled, attention has shifted to the next layer: the server. The UnJS project has built agnostic server tooling that works across ecosystems. Their minimal Node.js server framework H3 powers Nitro, a Vite-backed server runtime, which in turn enables Vinxi, an application bundler that abstracts both. Nitro already runs under Nuxt, Analog, and SolidStart; SolidStart also uses Vinxi. For platforms, that reach means supporting one of these frameworks effectively covers the others with no extra adapter work. The payoff is shared across framework authors, platforms, and developers, who gain transferable skills and less vendor lock-in.

Platform-Level Building Blocks

Serverless providers have taken note. Netlify's Platform Primitives give frameworks and developers direct access to generic features — incremental static regeneration, image optimization, and key/value storage — without framework authors having to implement or backport them. This is a notable shift: previously, a feature had to land in a framework first and then receive support from the platform of choice. Now, on Netlify, those capabilities are available immediately to every framework in one stroke.

Netlify Platform Primitives comprise three features:

  1. Image CDN — a content delivery network for images that handles format transformation and size optimization through URL query strings.
  2. Caching — primitives for the server runtime that manage browser, server, and CDN caching directives.
  3. Blobs — an always-available key/value storage option exposed through the platform SDK.

Image CDN

Images served from a /public directory can be delivered through Netlify's image optimization endpoint at /.netlify/images. That means no sharp package, no build-time asset transformation, and no image optimization dependency in your stack. In SolidStart, a small Image component can convert formats — for instance, defaulting to .webp with quality reduced to 75%, a pragmatic default that yields significant size savings without perceptible loss on large images.

import { type JSX } from "solid-js";

const SITE_URL = "https://example.com";

interface Props extends JSX.ImgHTMLAttributes<HTMLImageElement> {
  format?: "webp" | "jpeg" | "png" | "avif" | "preserve";
  quality?: number | "preserve";
}

const getQuality = (quality: Props["quality"]) => {
  if (quality === "preserve") return"";
  return `&q=${quality || "75"}`;
};

function getFormat(format: Props["format"]) {
  switch (format) {
    case "preserve":
      return"  ";
    case "jpeg":
      return `&fm=jpeg`;
    case "png":
      return `&fm=png`;
    case "avif":
      return `&fm=avif`;
    case "webp":
    default:
      return `&fm=webp`;
  }
}

export function Image(props: Props) {
  return (
    <img
      {...props}
      src={`${SITE_URL}/.netlify/images?url=/${props.src}${getFormat(
        props.format
      )}${getQuality(props.quality)}`}
    />
  );
}

Caching

Netlify caches static artifacts aggressively — by default for 365 days until redeployment or manual flush. Server and edge functions, however, are dynamic by nature and receive no default caching, to avoid serving stale responses. In production, adding proper cache headers on these functions is often the cheapest way to cut processing time and cost.

The first 80% of optimization is simply setting a Cache-Control header. For instance, a typical strategy uses:

{
  "cache-control": "public, max-age=0, stale-while-revalidate=86400"

}
  • public: allow shared caches to store the response.
  • max-age=0: mark the resource immediately stale.
  • stale-while-revalidate=86400: within 24 hours, serve the stale resource while revalidating in the background.

For content that can live longer, a fresh-for-a-day policy is common:

{
  "cache-control": "public, max-age=86400, must-revalidate"

}
  • public: allow shared caches.
  • max-age=86400: the resource stays fresh for one day.
  • must-revalidate: once stale, the cache must revalidate before responding.

Caching is effectively key/value storage: the platform derives a cache key from the request method and URL, with the Vary response header letting you broaden the differentiation. The Netlify-Vary header extends the concept by allowing the key to vary not just by header, but by specific header values. Supported variations include:

  • query: differ by values of some or all query parameters.
  • header: differ by values of specific request headers.
  • language: differ by languages from Accept-Language.
  • country: differ by country from GeoIP on the request IP.
  • cookie: differ by the value of specific request cookie keys.

Blob Storage

Blob storage is a highly available key/value store suited for frequent reads and infrequent writes. It is provisioned and available automatically for every Netlify project; data can be written from runtime code or a deployment-specific store. Below is an example of an Action Function in SolidStart registering a "likes" counter:

import { getStore } from "@netlify/blobs";
import { action } from "@solidjs/router";

export const upVote = action(async (formData: FormData) => {
  "use server";

  const postId = formData.get("id");
  const postVotes = formData.get("votes");

  if (typeof postId !== "string" || typeof postVotes !== "string") return;

  const store = getStore("posts");
  const voteSum = Number(postVotes) + 1)
    
  await store.set(postId, String(voteSum);

  console.log("done");
  return voteSum
  
});

Details and additional examples are in the @netlify/blobs API documentation.

Primitives Over Monoliths

Shared, high-quality primitives let framework creators build thin, adaptable integrations rather than platform-specific monoliths. The focus shifts to user experience and concrete use cases instead of vendor internals. Deeply integrated, all-in-one tooling can move fast, but it locks the ecosystem in. Primitives built on open foundations are the more sustainable path — for frameworks, platforms, teams, and the developers who move between them.