DEV Community

miccho27
miccho27

Posted on

490+ Calculator Tools with Zero Hosting Cost — Architecture Deep Dive

I built a site with 490+ free calculator tools — BMI, loan payments, unit conversions, tax calculators — all statically generated with Next.js. Monthly hosting cost: $0.

Here's the architecture behind keisan-tools.

The Problem

Japanese users search for specific calculators constantly. "BMI計算" (BMI calculator), "住宅ローン計算" (mortgage calculator), "年齢計算" (age calculator). Each query has moderate search volume with surprisingly low competition.

Instead of building each tool by hand, I built a system that generates tools from configuration.

Architecture Overview

keisan-tools/
├── data/
│   └── tools.json          # 490+ tool definitions
├── app/
│   └── [category]/
│       └── [slug]/
│           └── page.tsx     # Dynamic route template
├── lib/
│   ├── calculator.ts        # Calculation engine
│   └── tools.ts             # Tool loader + search
└── next.config.js           # Static export config
Enter fullscreen mode Exit fullscreen mode

The Tool Definition Format

Each calculator is a JSON object:

{
  "slug": "bmi-calculator",
  "category": "health",
  "title": "BMI計算ツール",
  "description": "身長と体重からBMIを計算",
  "inputs": [
    { "name": "height", "label": "身長 (cm)", "type": "number", "min": 100, "max": 250 },
    { "name": "weight", "label": "体重 (kg)", "type": "number", "min": 20, "max": 300 }
  ],
  "formula": "weight / ((height / 100) ** 2)",
  "output_label": "あなたのBMI",
  "output_unit": "",
  "result_ranges": [
    { "max": 18.5, "label": "低体重", "color": "blue" },
    { "max": 25, "label": "普通体重", "color": "green" },
    { "max": 30, "label": "肥満(1度)", "color": "orange" },
    { "max": 999, "label": "肥満(2度以上)", "color": "red" }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Add a JSON entry → get a fully functional calculator with:

  • Responsive UI with input validation
  • SEO metadata (title, description, canonical URL)
  • JSON-LD structured data (WebApplication schema)
  • Category navigation
  • Related tools sidebar

Zero code changes needed.

Static Generation at Scale

Next.js generateStaticParams creates all 490+ pages at build time:

export async function generateStaticParams() {
  const tools = getAllTools();
  return tools.map(tool => ({
    category: tool.category,
    slug: tool.slug,
  }));
}
Enter fullscreen mode Exit fullscreen mode

Build stats:

  • 490+ pages generated in ~50 seconds
  • Each page is a static HTML file served from Vercel's CDN
  • No server-side rendering — pure static

SEO Strategy

JSON-LD Structured Data

Every tool page includes:

{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "BMI計算ツール",
  "applicationCategory": "UtilityApplication",
  "operatingSystem": "Any",
  "offers": { "@type": "Offer", "price": "0", "priceCurrency": "JPY" }
}
Enter fullscreen mode Exit fullscreen mode

Category Index Pages

20+ category pages with internal links to every tool in that category. This creates a strong internal link structure that search engines love.

Sitemap

Auto-generated sitemap with all 490+ URLs submitted to Google Search Console.

Performance

Metric Score
Lighthouse Performance 95+
First Contentful Paint < 1s
Time to Interactive < 1.5s
Cumulative Layout Shift < 0.05
Bundle size (gzipped) ~80KB

Static HTML + CDN = fast everywhere in the world.

Categories Breakdown

Category Count Examples
健康 (Health) 35 BMI, calories, ideal weight
金融 (Finance) 68 Loan, compound interest, tax
数学 (Math) 45 Percentage, ratio, statistics
日時 (Date/Time) 28 Age calculator, date diff
単位変換 (Units) 52 Length, weight, temperature
不動産 (Real Estate) 22 Mortgage, rent vs buy
投資 (Investment) 31 NISA, iDeCo, dividends
エネルギー (Energy) 18 Solar panel, electricity
副業 (Side Business) 14 Take-home pay, tax

Key Takeaway: Configuration Over Code

Don't build 490 pages. Build 1 page that reads 490 configurations.

This pattern applies to any content-heavy static site:

  • Recipe sites → ingredients + steps as JSON
  • Product comparisons → specs as JSON
  • API documentation → endpoint definitions as JSON

If pages share the same layout but different data, SSG + JSON is the answer.

Tech Stack

  • Next.js 16 (App Router, SSG)
  • TypeScript + Tailwind CSS
  • Vercel (free tier hosting)
  • Google Analytics 4 (G-3R1LVHX9VJ)

Total monthly cost: $0.

Try it: keisan-tools.vercel.app


Have you built large-scale static sites? What was your experience with SSG at hundreds or thousands of pages? Let me know in the comments.

Top comments (0)