Skip to Content
Getting StartedVite Build

Vite Build

StatixFlow uses Vite 7 as the development server and production build tool. Vite compiles Tailwind CSS v4 from your source files, bundles JavaScript, and outputs ready-to-deploy HTML into the dist folder.

For Tailwind-specific setup details, see the official Tailwind + Vite guide .

If you only need to tweak text or images on finished pages, see Customize Production Ready HTMLs. Use this guide when you change HTML structure, add Tailwind classes, edit CSS or JavaScript under assets/, or need a fresh production build.

Prerequisites

  1. Install Node.js  (Vite 7 requires Node.js version 20.19+, 22.12+.).
  2. Open a terminal in the root of the downloaded template (the folder that contains package.json, vite.config.ts, and your .html files).
  3. See File Structure if you are unsure which folder is the project root.

Install dependencies

From the template root:

npm install

This reads package.json and package-lock.json and installs packages into node_modules.

npm scripts reference

ScriptCommandPurpose
devvite --hostLocal development with hot reload
buildnode build.jsProduction build into dist

Development

Start the Vite dev server with live reload:

npm run dev

Vite serves the project on your local network (--host is enabled in the dev script). Open the URL shown in the terminal—typically http://localhost:5173—and navigate to the HTML page you are editing (for example index.html).

While the dev server is running, edit files in the project root and under assets/ —not in dist.

  • HTML — Change page structure and content in .html files at the project root (for example index.html, about.html). To add a brand-new page, follow Adding a new HTML page.
  • JavaScript — Adjust behavior in assets/js/.

Styling with Tailwind

Style pages with Tailwind utility classes on your HTML elements—classes such as flex, gap-4, text-sm, and bg-primary. With the dev server running, Vite compiles any new or updated utilities into CSS automatically. See the Tailwind CSS documentation  for utility class reference, responsive design, and v4 features.

When you need styling that is shared across pages or goes beyond a single utility, open assets/css/style.css. That file is the template’s main stylesheet (linked from each HTML page) and is where you:

  • Define design tokens — theme colors, fonts, and variables (:root, @theme).
  • Add custom utility classes — reusable utilities in @layer utilities (for example bg-white-stripe).
  • Add component styles — repeated patterns in @layer components (for example Swiper pagination or scroll-highlight links).

Default theme variables

The template ships with a small semantic color palette and one typography token. Values are declared in :root, then exposed to Tailwind through @theme inline so you can use them as utilities (bg-primary, text-muted-foreground, border-border, and so on).

How it works

  1. :root — Raw CSS custom properties (for example --primary, --background). Edit these when you want to change the theme globally.
  2. @theme / @theme inline — Maps those properties to Tailwind’s --color-* and --font-* namespace so the compiler generates matching utilities.
  3. @layer base — Applies defaults to the page (for example body uses bg-background and text-foreground).

Typography

TokenDefaultTailwind usage
--font-sans"Instrument Sans", sans-seriffont-sans

Semantic colors

RoleCSS variable (:root)Default (summary)Example utilities
Page--background, --foregroundSlate-50 page, dark green-tinted textbg-background, text-foreground
Brand--primary, --primary-foregroundNeutral-900 / whitebg-primary, text-primary-foreground
Accent brand--secondary, --secondary-foregroundBlue-800 / blue-50bg-secondary, text-secondary-foreground
Muted--muted, --muted-foregroundGray-200 / gray-blue textbg-muted, text-muted-foreground
Highlight--accent, --accent-foregroundViolet-100 / violet-700bg-accent, text-accent-foreground
Border--borderLight neutral (oklch)border-border
Card--color-card, --color-card-foreground (via @theme inline)White card on --foreground textbg-card, text-card-foreground
Focus ring--color-ring (via @theme inline)15% primary mixring-ring
Input--color-input (via @theme inline)Same as borderborder-input

Certain color variables come in pairs: a surface token for the background and a matching foreground token for the text as shown for example in the Brand and Accent brand colors above.

Status colors (alerts, badges, feedback UI)

RoleExample utilities
Successbg-status-success, text-status-success-foreground
Infobg-status-info, text-status-info-foreground
Warningbg-status-warning, text-status-warning-foreground
Destructivebg-status-destructive, text-status-destructive-foreground

Other

TokenPurpose
--stripe-opacityOpacity for custom stripe utilities (bg-white-stripe, diagonal variants) — default 18%

:root defaults (excerpt)

:root { --background: var(--color-slate-50); --foreground: oklch(0.1445 0.0148 121.37); --primary: var(--color-neutral-900); --primary-foreground: var(--color-white); --secondary: var(--color-blue-800); --secondary-foreground: var(--color-blue-50); /* status-success, status-info, status-warning, status-destructive … */ --muted: var(--color-gray-200); --muted-foreground: oklch(0.6 0.03 251.66); --accent: var(--color-violet-100); --accent-foreground: var(--color-violet-700); --border: oklch(0.9097 0 0); --stripe-opacity: 18%; }

Bridging into Tailwind (@theme inline)

@theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); /* …maps every semantic token to --color-* … */ --color-ring: color-mix(in oklch, var(--color-primary) 15%, transparent); --color-card: var(--color-white); --color-card-foreground: var(--foreground); }

To rebrand the template, adjust the values under :root in assets/css/style.css (and @theme if you add new font families).

Adding a new HTML page

Vite treats every .html file in the project root (next to package.json) as its own page entry. When you add a new template—for example services.html—place it there, not inside dist/. The file is picked up automatically by npm run dev and included in npm run build with no extra Vite configuration.

The fastest approach is to duplicate an existing page that is closest to what you need (contact.html or privacy-policy.html for a simple inner page, index.html for a full landing layout), rename the file, then edit the title, navigation links, and main content.

Basic page structure

Below is a basic page skeleton. Key details are included in the HTML comments:

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <!-- Favicon and Viewport --> <link rel="icon" type="image/svg+xml" href="/imgs/generic/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- Google Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&display=swap" rel="stylesheet" /> <!-- Main Stylesheet --> <!-- For Production Mode, it'll be <link href="assets/css/style.min.css" rel="stylesheet" /> this is done automatically when you run npm run build --> <link href="assets/css/style.css" rel="stylesheet" /> <!-- Page Description --> <meta name="description" content="StatixFlow is a premium platform designed to optimize performance, growth strategy, and automate your business processes." /> <!-- Page Title --> <title>Your Page Title - StatixFlow</title> </head> <body> <!-- Start: Page Header --> <header class="fixed top-0 right-0 left-0 z-50 py-4" data-animated-scroll-header> <div class="container mx-auto px-4"> <div class="flex items-center justify-between rounded-2xl bg-white p-4 shadow-xl sm:py-2"> <!-- Start: Logo --> <a href="index.html" class="flex items-center gap-2 text-sm font-bold tracking-wider uppercase"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> <path d="M13 3L4 14h7l-2 7 9-11h-7l2-7z" /> </svg> <span>StatixFlow™</span> </a> <!-- End: Logo --> <!-- Start: XL+ Screens Navigation --> <nav class="hidden items-center gap-10 text-sm font-medium xl:flex" data-desktop-nav> <a href="home.html" data-active-link class="text-foreground transition-colors duration-300 ease-in-out hover:text-foreground/70 data-active-link:text-muted-foreground">Home</a> <a href="about.html" class="text-foreground transition-colors duration-300 ease-in-out hover:text-foreground/70 data-active-link:text-muted-foreground">About</a> ... </nav> <!-- End: XL+ Screens Navigation --> <!-- Start: Header Actions --> <div class="flex items-center gap-6"> <!-- Start: Header CTA Button --> <a href="#" class="group hidden items-center justify-center gap-2 rounded-full border border-primary bg-transparent px-4 py-3 text-sm font-medium text-black sm:inline-flex"> <span class="relative overflow-hidden"> <span class="relative block h-full translate-y-0 transition-transform duration-300 ease-in-out group-hover:-translate-y-full">Send a message</span> <span class="absolute top-0 left-0 block h-full translate-y-full transition-transform duration-300 ease-in-out group-hover:translate-y-0">Send a message</span> </span> <span class="translate-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-2"> <i data-lucide="chevron-right" class="size-4"></i> </span> </a> <!-- End: Header CTA Button --> <!-- Start: Mobile Navigation Trigger --> <button class="group flex cursor-pointer items-center gap-2 xl:hidden" data-mobile-nav-trigger> <span class="text-xs font-medium tracking-widest text-foreground uppercase">Menu</span> <span class="flex h-3 w-4 flex-col justify-between"> <span class="block h-px w-full origin-center bg-current transition-all duration-300 ease-in-out group-open:translate-y-[5.5px] group-open:rotate-45"></span> <span class="block h-px w-full origin-center bg-current transition-all duration-300 ease-in-out group-open:opacity-0"></span> <span class="block h-px w-full origin-center bg-current transition-all duration-300 ease-in-out group-open:-translate-y-[5.5px] group-open:-rotate-45"></span> </span> </button> <!-- End: Mobile Navigation Trigger --> </div> <!-- End: Header Actions --> </div> </div> </header> <!-- End: Page Header --> <!-- Start: Mobile Navigation Overlay --> <div class="pointer-events-none fixed inset-0 z-60 bg-black/40 opacity-0 transition-all duration-300 ease-in-out open:pointer-events-auto open:opacity-100" data-mobile-nav-overlay></div> <!-- End: Mobile Navigation Overlay --> <!-- Start: Mobile Navigation Sheet --> <div class="fixed top-0 left-0 z-70 flex h-screen w-3/4 -translate-x-full flex-col bg-black text-white transition-transform duration-300 ease-in-out open:translate-x-0" data-mobile-nav-sheet> <div class="flex min-h-0 flex-1 flex-col justify-between overflow-y-auto p-10 md:p-20"> <div class="grid grid-cols-1 gap-8 md:grid-cols-[180px_1fr] md:gap-10"> <!-- Social --> <div> <h2 class="mb-6 text-xs font-medium tracking-widest text-muted-foreground uppercase"> Social </h2> <ul class="space-y-4 text-lg sm:space-y-6"> <li> <a href="#" class="flex items-center gap-2 opacity-100 transition-opacity duration-300 ease-in-out hover:opacity-70" data-mobile-nav-link aria-label="Follow us on X (Twitter)"> <img src="/imgs/social/light/x.svg" alt="X" width="48" height="48" class="size-4" loading="lazy" /> <span>X (Twitter)</span> </a> </li> ... </ul> </div> <!-- End: Social --> <!-- Start: Menu --> <div> <h2 class="mb-6 text-xs font-medium tracking-widest text-muted-foreground uppercase"> Menu </h2> <ul class="space-y-4 text-lg font-medium sm:space-y-6 md:text-4xl"> <li> <a href="home.html" class="transition-opacity duration-300 ease-in-out hover:opacity-70 data-active-link:text-muted-foreground" data-active-link data-mobile-nav-link>Home</a> </li> <li> <a href="about.html" class="transition-opacity duration-300 ease-in-out hover:opacity-70 data-active-link:text-muted-foreground" data-mobile-nav-link>About</a> </li> ... </ul> </div> <!-- End: Menu --> </div> <!-- Start: Other information --> <div class="mt-auto pt-8 md:pt-10"> <p class="mb-6 text-xs font-medium tracking-widest text-muted-foreground uppercase"> Get in touch </p> <a href="mailto:info@statixflow.com" class="text-lg font-medium transition-opacity duration-300 ease-in-out hover:opacity-70">info@statixflow.com</a> </div> <!-- End: Other information --> </div> </div> <!-- End: Mobile Navigation Sheet --> <!-- Start: Smooth Scroll Area --> <div id="smooth-wrapper"> <div id="smooth-content"> <!-- For smooth scroll to work as expected, all content should be inside #smooth-wrapper & #smooth-content. All fixed position elements should be outside of #smooth-wrapper --> <!-- Start: Main Container --> <main data-main-container> <!-- ... All main sections/divs go here ... --> <!-- Copy <footer> from an existing page when you need the standard site footer --> </main> <!-- End: Main Container --> </div> </div> <!-- End: Smooth Scroll Area --> <!-- Main JavaScript --> <!-- For Production Mode, it'll be <script src="assets/js/main.min.js"></script> this is done automatically when you run npm run build --> <script type="module" src="assets/js/main.js"></script> </body> </html>
  • Images and static files — Place files in public/ and reference them with a leading slash, for example src="/imgs/hero/photo.jpg".
  • Links between pages — Use sibling .html paths from the project root, for example href="contact.html" or href="index.html".
  • In-page anchors — Use href="#section-id"; smooth scrolling for hash links is handled when the smooth-scroll wrapper is present.

Checklist after adding a page

  1. Save the new .html file in the project root.
  2. Update navigation links in the header and mobile menu on other pages if the page should appear in the menu.
  3. Run npm run dev and open http://localhost:5173/your-page.html.
  4. Run npm run build and confirm the new file appears in dist/ before deployment.

Production build

Generate optimized output for deployment:

npm run build

The build.js file which is powered by Vite, writes compiled HTML, CSS, and JavaScript to the dist folder. Upload the contents of dist to your host, or use that folder as the publish root in your deployment pipeline.

Code formatting (Prettier)

Prettier is a developer tool for formatting source files. It does not run during npm run dev or npm run build and is not required to deploy the site.

The template ships with Prettier  and prettier-plugin-tailwindcss  in devDependencies. .prettierrc enables the Tailwind plugin and tells it which stylesheet defines your theme:

{ "plugins": ["prettier-plugin-tailwindcss"], "tailwindStylesheet": "./assets/css/style.css" }
SettingPurpose
pluginsSorts Tailwind utility classes in class attributes into a stable, recommended order when you format a file.
tailwindStylesheetMust match the main stylesheet linked from your HTML (assets/css/style.css). The plugin reads it so sorting respects custom utilities and semantic tokens from @theme (for example bg-primary, text-muted-foreground).

Use Prettier from your editor (format on save) or from the template root:

npx prettier --write .

There is no format script in package.json. If you change the path to your main CSS file, update tailwindStylesheet in .prettierrc to match.

Troubleshooting

npm install or npm run dev fails immediately

  • Confirm node -v is 20.19+ or 22.12+.
  • Delete node_modules and run npm install again.
  • Use npm 9+ if the lockfile causes install errors on an older npm.

Tailwind classes do not appear after editing HTML

  • Run npm run dev or npm run build so Tailwind can compile utilities into CSS. Editing dist alone will not pick up new classes (see Customize Production Ready HTMLs).
Last updated on