DEV Community

Alessandro Binda
Alessandro Binda

Posted on • Originally published at github.com

How I Built 100 Industry-Specific Website Templates and Why I'm Giving Them Away (Next.js + TypeScript)

Last week I open-sourced a project I've been building for several months: 100 website components across 12 industry verticals, organized as a pnpm monorepo, MIT licensed, free to deploy.

GitHub: https://github.com/Alessandro114/scala-sites
Live demo: https://scala-sites.vercel.app

This post covers three things: the technical architecture decisions, the business reasoning behind giving it away, and a cost analysis that motivated the whole thing.

The Problem with Generic Templates

Every website template marketplace sells you the same thing: a generic hero component, a features grid, a testimonials section, a contact form. The assumption is that good design transfers across industries.

It doesn't.

A restaurant's website needs to answer: what's on the menu today, can I book a table right now, what do real customers say. A law firm's website needs to answer: do you handle my specific type of case, how do I get a consultation, what's your track record. A gym's website needs to answer: what classes run when, can I sign up directly, what membership costs.

These are structurally different problems. A generic <Hero> component with a title and a button doesn't solve any of them particularly well.

So I built per-vertical hero components, per-vertical JSON-LD schemas, and per-vertical component sets.

The Theming System

Rather than a global design token system, I went with three base themes and a createCustomTheme() override function:

import { createCustomTheme, themeToStyleObject } from '@scala-sites/themes'

const restaurantTheme = createCustomTheme('classic', {
  primary: '#1e3a5f',
  accent: '#c9a84c',
  background: '#fafaf8',
})

// Use in your layout:
const style = themeToStyleObject(restaurantTheme)
// Returns: { '--color-primary': '#1e3a5f', '--color-accent': '#c9a84c', ... }
Enter fullscreen mode Exit fullscreen mode

The three base themes:

  • Minimal — white background, Inter font, subtle borders. Works for luxury brands, professional services.
  • Bold — dark background, Bebas Neue headings, sharp edges. Works for gyms, nightlife, automotive.
  • Classic — warm tones, Playfair Display serif, soft radius. Works for traditional restaurants, heritage brands, legal.

No CSS-in-JS runtime. No Tailwind config rebuild when you change a color. Pure CSS variables injected at the root. This means theme switching is a single property change, and SSR works without hydration mismatches.

JSON-LD by Vertical

The @scala-sites/core SEO package handles structured data automatically based on which vertical you're in:

  • dineos (restaurant) emits FoodEstablishment schema with servesCuisine, hasMenu, priceRange
  • legalos (law firm) emits LegalService with areaServed, knowsAbout
  • clinicos (medical) emits MedicalBusiness with medicalSpecialty
  • gymos emits SportsActivityLocation

The FAQAccordion component — shared across all verticals — always emits FAQPage schema, which Google uses to populate rich results directly in search.

The goal is that a developer using these templates doesn't need to think about structured data. It's correct by default.

Hero Architecture Decision

The most debated decision in the repo was whether to have a single parameterized <Hero> component or per-vertical hero implementations.

I went per-vertical. Here's the argument:

A restaurant hero needs: full-bleed video or image, overlay gradient, reservation CTA as primary action, menu CTA as secondary, possibly an urgency element ("booking fast this weekend").

A gym hero needs: class schedule preview above the fold, membership CTA, possibly a live class counter or next-class timer.

A law firm hero needs: practice area selector, consultation CTA, social proof counter (cases handled, years experience) — but restrained, because aggressive sales tactics read wrong in legal contexts.

These aren't just different slot content. They're different interaction models. Forcing them into one component either makes the component so generic it adds no value, or makes it so complex with conditional logic that it becomes harder to maintain than separate components.

Separate components means more code. But each component is smaller, more readable, and can evolve independently. A restaurant owner updating their hero doesn't need to understand the gym hero's class-schedule logic.

The Cost Analysis

The second thing I built is https://analyze.get-scala.com — a tool that shows what a typical SMB pays for its digital stack.

I spent a week on pricing research across every major tool category. The result for a typical 3-location restaurant, using annual billing rates:

Category Tool Monthly
Website builder WordPress.com Business $40
Email (5 users) Google Workspace $35
CRM HubSpot Starter $40
Booking Calendly (2 seats) $20
Live chat + AI Tidio + Lyro $68
WhatsApp API 2K marketing msgs $40
SEO SEMrush Pro $140
Reviews Trustpilot Starter $99
Email marketing Mailchimp (2K contacts) $27
Forms Typeform Basic $29
Social scheduling Buffer (3 channels) $15
Analytics GA4 $0
Total 14 vendors $555/mo

That's $6,660/year. And this is the conservative version — with Intercom instead of Tidio you hit $1,500/month.

Three things I found notable in the research:

  • Mailchimp's free tier went from 2,000 contacts (2022) to 500 (2023) to 250 (2026). They degrade it deliberately to force upgrades.
  • Ahrefs raised Lite from $99 to $129 in March 2026 with no feature changes.
  • SiteGround intro pricing is as low as $2.99/month; renewal rates hit $17.99/month — a 6x jump that small business owners routinely don't notice until it hits.

The full pricing data (with sources) is in COST-COMPARISON-DATA.md in the repo.

Why Give It Away

My company sells an AI operating system for SMBs — real-time booking, WhatsApp automations, multi-location CRM. The website is the entry point, not the product.

The templates are free because reaching business owners early — before they've committed to a fragmented stack — is worth more than charging for templates. Give them something genuinely useful. Be present before anyone asks to see a pitch deck.

It also creates a forcing function: MIT licensed code has to be good enough to fork. That pressure is useful.

Performance

The demo app (Next.js 14, App Router, SSG) scores 97-100 on Lighthouse across all vertical pages. Static generation means zero TTFB on cached routes. The CSS variable theming adds zero runtime overhead — it's compiled at build time.

No JavaScript is required to render any template above the fold. Booking widgets and interactive components lazy-load only when scrolled into view.

Try It

GitHub: https://github.com/Alessandro114/scala-sites
Cost analyzer: https://analyze.get-scala.com
Live demo: https://scala-sites.vercel.app

Star the repo if it's useful. Open an issue if you want a vertical that's not there yet. PRs welcome — especially for industries outside the current 12.


Top comments (0)