Skip to main content

Hosted in Palitana, Gujarat \u00b7 Tier-I Reliability \u00b7 <5ms Local Latency

The hosting stack behind webhost24.in: Astro 7, Svelte 5, and the Palitana CDN

The exact stack that powers webhost24.in: Astro 7 + Svelte 5 + Tailwind 4 + a per-app OG image generator. The full architecture, build pipeline, and deployment story.

Cover image for The hosting stack behind webhost24.in: Astro 7, Svelte 5, and the Palitana CDN

The R221 marketing site (this site you’re reading) is built on the following stack. This post is the canonical source of truth for the architecture.

Frontend

  • Astro 7 as the meta-framework. Builds the site to static HTML via output: "static". The @astrojs/node adapter serves the build in standalone mode so the same Docker image can run on any container host.
  • Svelte 5 for the small set of interactive islands (mobile menu, cookie banner, sticky header, billing cycle toggle). Astro components are HTML by default; Svelte is opt-in per island.
  • Tailwind 4 via the Vite plugin (the new style). Brand-color palette: brand primary #002071, secondary #FAA21B, success #16A34A, error #DC2626. All tokens declared once in globals.css.
  • bits-ui for the small set of unstyled accessible primitives (accordion, sheet/dialog, switch, tabs, tooltip, select). Drop-in replacement for the R220 Radix UI setup.

Per-app OG image generator

A custom Node + sharp script (scripts/build-app-og-pngs.mjs) generates one 1200x630 PNG per app MDX file at prebuild time. Each PNG uses the app’s brand colour as the background + the app title + a 60-char wrap of the excerpt as the foreground. Wired into the prebuild script chain so the PNGs are regenerated before every astro build.

Build pipeline

The npm run build command is a 3-step chain:

  1. prebuild - runs build-og-png.mjs + build-llms-txt.mjs
    • build-app-og-pngs.mjs.
  2. build - runs astro build (renders the static HTML
    • the JS chunks for the islands).
  3. start - the dev server (not part of CI; for local npm run dev only).

The output is a static dist/client/ (~2.9 MB across 70+ HTML pages + 12 brand assets + 17 per-app OG PNGs)

  • a server entrypoint at dist/server/entry.mjs that runs on port 2828 via @astrojs/node standalone.

Deployment

The Docker image (single-stage, alpine-based) is built from the repo’s Dockerfile. The build step does npm ci, then runs npm run build. The runtime step copies dist/server/entry.mjs + dist/client/ into the container image and runs node ./dist/server/entry.mjs.

The same image is deployed to Palitana on a Kubernetes cluster managed by our ops team. Health-checks hit /healthz (returns {status: "ok"}). Cache-Control headers are set in the Astro middleware (s-maxage 7d for /fonts/, s-maxage 1d for /apps/ + /brand/).

Why this stack

Astro ships 0 JS by default; only the islands contribute. Our largest island bundle is the cookie banner (~15 KB gzipped). Total JS payload across the public surface is ~30 KB gzipped, which is well under the 50 KB per-page budget from spec §9.

Svelte 5’s $state / $derived reactivity is small enough to render in 4-5 KB gzipped per island. The old React 19 + Radix UI combo in the R220 setup shipped ~120 KB gzipped of JS. The 4x reduction is the biggest perf win of the R221 cut.

Written by

WebHost24

Hosted in India, written in English

  • 5 min read

Share this post

Need help?

Talk to sales on WhatsApp

Our team replies during Indian business hours. Tell us which plan you're looking at and we'll match you with the right setup.