Skip to content

Repository files navigation

Duty Check — Kenya Car Import Duty Calculator

The Kenya car import-duty calculator that shows you exactly how KRA arrives at your duty — step by step, from the official CRSP valuation to every tax line item.

Live at: www.dutycheck.co.ke

Duty Check is a fast, transparent, SEO-first duty calculator for importing vehicles into Kenya. Pick a vehicle by category → make → model → year and it shows the full KRA breakdown: CRSP lookup, tax-stripping, age-based depreciation, and every duty component through to the total payable.


Features

  • Full CRSP database — every vehicle in the official KRA CRSP list of July 2025 (11 categories, ~5,683 entries).
  • Transparent methodology — shows the ÷2.4469 valuation factor, depreciation, and each duty line (Import Duty, Excise, VAT, IDF, RDL) rather than a black-box total.
  • Cascading selector — category → make → model → year, with real URL paths pushed to the address bar (e.g. /suv/toyota/harrier/2022/).
  • Shareable, indexable pages — every category, make, model, and year has its own static page and canonical URL.
  • Dark / light mode.
  • Per-page SEO — canonical, Open Graph, and Twitter tags on every page, plus JSON-LD structured data (BreadcrumbList everywhere; Car/Vehicle on model pages; FAQPage on year pages; WebApplication + WebSite on the homepage).
  • Generated sitemaps + robots.txt — a sitemap index, a main sitemap, and one sitemap per category.
  • Google Analytics 4 on all pages.

Tech Stack

  • Build tool: Vite 7
  • Styling: Tailwind CSS v4 via @tailwindcss/cli and @tailwindcss/vite
  • App code: vanilla JavaScript (ES modules, "type": "module") — no UI framework
  • Data pipeline: Python 3 (pandas/openpyxl) for parsing the KRA CRSP spreadsheet
  • Rendering: a single shared renderer (plugins/render.js) used for both dev SSR and prod static generation
  • Hosting: Vercel (static output)
  • Analytics: Google Analytics 4

Project Structure

dutycheck/
├── index.html                 # Homepage — interactive calculator shell
├── src/
│   ├── main.js                # Entry module loaded by index.html
│   ├── calculator.js          # Interactive cascading calculator (client-side)
│   ├── theme.js               # Dark/light mode toggle
│   └── style.css              # Tailwind source (compiled to public/css/styles.css)
├── plugins/
│   ├── render.js              # Shared page renderer (KRA formula + all page templates)
│   └── dev-render.js          # Vite middleware for on-the-fly SSR in dev
├── scripts/
│   ├── crsp_to_json.py        # Parse KRA CRSP .xlsx → intermediate JSON
│   ├── build_crsp_cascade.py  # Build data/crsp_cascade.json (category→make→model)
│   └── generate_pages.js      # Prod: write static HTML pages + sitemaps into dist/
├── data/
│   └── crsp_cascade.json      # CRSP July 2025, 11 categories, ~5,683 entries
├── public/                    # Static assets copied as-is (robots.txt, css/, data/)
├── vite.config.js
└── vercel.json                # Vercel build config

Note: public/css/styles.css is generated by npm run build:css and is gitignored.


Getting Started

Prerequisites

  • Node.js 18+ (for Vite and the page generator)
  • Python 3 — only needed if you want to regenerate the CRSP data from the source spreadsheet

Install

npm install

npm scripts

Script What it does
npm run dev Compiles CSS, then starts the Vite dev server. A middleware plugin renders category/make/model/year routes on the fly (SSR).
npm run build Compiles CSS → runs vite build → runs scripts/generate_pages.js to write all static pages and sitemaps into dist/.
npm run build:css Compiles src/style.css to public/css/styles.css with Tailwind (minified).
npm run data Regenerates the CRSP data (python3 scripts/crsp_to_json.py && python3 scripts/build_crsp_cascade.py).

How It Works

The interesting architectural bit is that dev and prod share one renderer (plugins/render.js), which owns both the KRA duty formula and every page template (category, make, model, year).

  • Development (npm run dev): plugins/dev-render.js registers Vite middleware that intercepts requests. For any known route it calls renderUrl(pathname) and returns freshly rendered HTML. The homepage is served by Vite/index.html and hydrated by the client-side calculator in src/calculator.js.
  • Production (npm run build): after vite build, scripts/generate_pages.js walks the entire CRSP dataset and calls the same renderUrl() to write ~50,000+ static HTML files into dist/ — one per category, make, model, and valid import year. Because dev and prod use identical rendering logic, what you see locally is exactly what ships.

URL structure

/{category}/{make}/{model}/{year}/
e.g. /suv/toyota/harrier/2022/

Year pages exist for every year within Kenya's 8-year import rule (current year back through current − 8).

KRA duty formula

CRSP Value (official KRA July 2025 list)
  ÷ 2.4469                 → pre-depreciation value (strips embedded taxes)
  × (1 − depreciation)     → Customs Value (CV), depreciation by vehicle age

Import Duty  = CV × 25%
Excise Duty  = (CV + Import Duty) × 20%
VAT          = (CV + Import Duty + Excise Duty) × 16%
IDF          = CV × 2.25%   (minimum KES 5,000)
RDL          = CV × 1.5%
─────────────────────────────────────────
Total KRA Duty = Import Duty + Excise + VAT + IDF + RDL

Rates are per the Finance Act 2025 (Act No. 9 of 2025).


Data

The dataset is derived from the official KRA CRSP (Current Retail Selling Price) list of July 2025:

To regenerate data/crsp_cascade.json from the source spreadsheet:

npm run data

This runs scripts/crsp_to_json.py (parse the .xlsx) followed by scripts/build_crsp_cascade.py (normalise body types into the 11 display categories and build the category → make → model cascade the app consumes).


Deployment

Deployed on Vercel using vercel.json:

  • buildCommand: npm run build
  • outputDirectory: dist
  • installCommand: npm install

The canonical host is https://www.dutycheck.co.ke. DNS 301-redirects the naked apex domain to www, and every canonical, og:url, sitemap, and robots.txt reference uses the www host to keep Google Search Console from splitting signals between apex and www.


Roadmap

Done

  • Cascading calculator (category → make → model → year) with real URL paths
  • Dev SSR + prod static generation (~50k pages) from a shared renderer
  • Dark / light mode
  • Sitemaps (sitemap-index.xml + sitemap.xml + per-category sitemaps, incl. year pages) — entries only for pages actually written (consistency fix)
  • robots.txt with sitemap reference
  • Canonical host consolidated on www (fixes GSC apex/www split)
  • Structured data: WebApplication + WebSite (home), BreadcrumbList, FAQPage, Car (model/year)
  • Price-intent titles/descriptions ("price in Kenya") on model/year pages
  • Homepage optimized for head terms ("KRA car import duty calculator") + FAQ
  • Branded og:image share card (summary_large_image)
  • WhatsApp share button on every generated page (single-URL so the correct og card attaches)
  • Internal linking: "Related vehicles" + "Other years" modules on model/year pages (funnels link equity, improves indexation)
  • E-E-A-T provenance: CRSP date line + Car JSON-LD dateModified/publisher
  • Keyword tuning from Search Console data: category titles gained "Calculator", make titles gained "Prices", model/year descriptions gained "how much/cost/customs", homepage added tax/customs/valuation terms
  • Compare feature: /compare/{make-model}/{make-model}/ side-by-side pages (~20k, incl. cross-make) with interactive year selectors + sitemap-compare.xml
  • Cross-make compare generation (relatedVehiclesCrossMake)
  • Turbo Drive navigation (@hotwired/turbo vendored; GA page_view on turbo:load; idempotent calculator/theme re-init) — verified via full build + Playwright

SEO — next

  • Content guides: "How to import a car into Kenya", "Understanding CRSP" (informational traffic + backlinks)
  • FAW / commercial-vehicle title + content tuning (impressions but 0 clicks)
  • Indexation audit in GSC (indexed vs. "discovered – not indexed")
  • Off-page: backlinks / embeddable calculator widget / directory listings
  • Per-page dynamic OG images (currently one shared branded card)
  • External-links verification (KRA / Finance Act URLs — kenyalaw.org was unverifiable from CI, but the KRA links return 200)

Done (recent)

  • Link compare pages from model/year pages so they aren't orphaned (real /compare/ links via compareLinksHtml, verified to resolve)

Product / Growth

  • Insurance estimate widget (4–6% of CRSP) + "Get quotes" CTA
  • Finance pre-qualification CTA when duty + car cost is high
  • Model page as a fully self-contained interactive calculator (model pages already show a year table linking to year pages, but not an in-page interactive calculator)
  • Turbo-style navigation (@hotwired/turbo) for app-like transitions
  • Compare feature — /compare/{make-model}/{make-model}/

Working task tracking lives in todo.md.


Disclaimer

Duty Check is provided for guidance only. Duty figures are estimates based on the published KRA CRSP list and prevailing rates, and actual assessments can vary. Always verify with KRA or a licensed clearing agent before making import decisions.

About

Transparent KRA car import duty calculator for Kenya — shows the full formula, verified against the official CRSP list

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages