Kemenperin
Programs.
Programs for the Ministry of Industry, Republic of Indonesia — rebuilt across eight years. PHP 5 to PHP 8, React + Hono, and the Svelte + Go + Python platform running today.
Business Matching
Eight years, five stacks, one mission — the complete development history of Kemenperin’s Business Matching platform, from a PHP 5 monolith to the Svelte + Go + Python system running at bm-online.id today.
PHP 5 — The First Platform
The first incarnation of Business Matching for Kemenperin ran on PHP 5 — a classic server-rendered monolith where every page was generated on request. IKM (small & medium industry) actors could register a company, list products in a catalog, and submit matching requests ahead of ministry-run business matching events.
It did the job. Manufacturers adopted a digital matching channel for the first time, and ministry staff gained an admin view over participants. But the stack was aging fast: no dependency isolation, legacy mysql_* patterns in places, and an increasingly brittle deployment on shared hosting.
Legacy admin dashboard
Company directory
Matching request form
Proved the model — industry would match online — but the runtime had no headroom left.
PHP 8 — The Modernized Monolith
The second era rebuilt the platform on PHP 8 — same monolith shape, professional internals. Typed function signatures, Composer-managed dependencies, and PDO prepared statements replaced the legacy patterns. The registration and matching flows gained server-side validation that actually held up under real ministry events.
For the first time the codebase had tests covering the critical paths, and ministry staff got a dedicated admin panel to curate participants, approve companies, and schedule one-on-one matching sessions between buyers and producers.
Curated admin panel
Product catalog
Event reports
Same shape, professional internals — bought the platform years of stable service.
React + Hono — The Decoupled Era
Era three split Business Matching in two: a React SPA for participants and a Hono-powered TypeScript API serving the data. Decoupling unlocked a genuinely mobile-friendly experience for factory-floor users and let the API serve more than one consumer.
JWT-based auth replaced server sessions, PostgreSQL replaced MySQL, and the matching workflow became an explicit API contract instead of implicit page logic. The trade-off was real though — two codebases, two deploy pipelines, and validation rules duplicated on both sides.
React participant app
Hono API surface
Company profile, decoupled
A real API and a real SPA — but double the maintenance for a small team.
Svelte + Go — bm-online.id
The current production system at bm-online.id consolidates every lesson from the earlier eras. A Svelte/SvelteKit frontend delivers SSR speed with SPA ergonomics in a single codebase, while a Go backend serves the matching API with a tiny footprint and single-binary deploys.
Validation lives in shared schemas instead of duplicated client/server rules, the admin and public experiences share one deployment story, and infrastructure cost dropped to the lowest point in the platform’s history.
bm-online.id today
Matching workflow, current
Participant dashboard
One frontend, one backend, one deploy — the architecture the earlier eras were reaching for.
Svelte + Go + Python — The Intelligent Platform
Era five keeps the consolidated Svelte + Go shape and adds a Python service for the work Go shouldn’t do. The Svelte/SvelteKit frontend and Go API are unchanged in structure — Go still owns auth, the matching workflow, and ministry reporting — while a Python service handles document extraction, industry-sector classification, and embedding-based buyer–supplier recommendations.
Go calls the Python service over a typed internal API and stays the single public gateway, so the deployment story barely changed: one binary in front, one purpose-built service behind it. The result is the first era where the platform actively improves matches instead of just recording them.
Current platform, 2026
Embedding-based matching recommendations
Dashboard with match insights
Same deploy story, new brain — Go serves, Python thinks.
P3DN Fasilitasi
The facilitation arm of Kemenperin’s P3DN program — from paper-shaped request forms to a self-service portal running on the shared Svelte + Go platform.
PHP 5 — The Facilitation Desk
P3DN Fasilitasi — the facilitation arm of Kemenperin’s P3DN program (Peningkatan Penggunaan Produk Dalam Negeri) — started on the same PHP 5 stack as the early Business Matching platform. Companies submitted facilitation requests for TKDN certification and domestic-product verification through server-rendered forms, with documents tracked by hand inside a shared MySQL database.
The workflow was linear — request, review, facilitate, report — and a monolith could carry it. But document-heavy processes strained the simple upload pipeline, and every ministry reporting cycle meant manual exports assembled by staff.
Facilitation request form
Manual request tracking
Admin request list
Digitized the front door of the facilitation program — the paperwork behind it stayed paper-shaped.
PHP 8 — Structured Facilitation
The PHP 8 rebuild gave the facilitation workflow real structure. Requests moved through explicit stages — submitted, document review, field verification, facilitated, reported — instead of freeform status text. Document checklists became typed data rather than informal attachments, and staff could finally export the reports the ministry asked for every cycle.
Underneath, the same modernization as its sibling platform: Composer dependencies, PDO prepared statements, and tests around the review pipeline.
Staged review pipeline
Document checklist
Ministry reporting exports
Facilitation became a pipeline, not a pile — stages and checklists staff could trust.
React + Hono — Self-Service Facilitation
Era three moved facilitation to the decoupled stack: a React portal where companies could watch their own requests move through the pipeline, upload documents asynchronously instead of in one giant form post, and get notified on status changes — backed by the same Hono TypeScript API family as Business Matching.
Staff got a typed review queue with filters by stage, sector, and region. The API-first design meant the facilitation data could feed other ministry dashboards without scraping screens.
Self-service portal
Live status tracking
Staff review queue
Companies stopped calling for status updates — the portal told them first.
Svelte + Go — The Consolidated Platform
The current P3DN Fasilitasi system runs on the consolidated Svelte + Go platform shared with bm-online.id. The SvelteKit frontend handles the public request flow and the staff console in one codebase, while the Go backend serves document uploads, the review pipeline, and ministry reporting from a single binary.
Consolidating the two Kemenperin systems onto one stack cut the maintenance surface in half — one deploy pipeline, one set of shared validation schemas, one operations story for both programs.
Current platform home
Facilitation request flow
Staff console
Two programs, one stack — the platform both systems were converging toward.
Five eras.
One platform.
Still running.
Kemenperin's programs — started on PHP 5, consolidated on a Svelte + Go + Python stack built to carry them into the next era.