# Matthews Wong > Software Engineer from Indonesia working as an ERP Developer, DevOps Engineer, and full-stack web developer. He specialises in DevOps & Cloud Infrastructure, ERP Systems, and Web App Development. Currently an AI Forward Deployed Engineer at Commsult Indonesia, building the company's MCP Console and Gateway. Matthews Wong builds and operates production systems — from CI/CD pipelines and container orchestration to ERP modules (Accounts Payable/Receivable, approvals, inventory, HR workflows) and commercial web applications. He studied Information Technology at Swiss German University, Tangerang, and has held roles across DevOps engineering, software development engineering in test (SDET), data science, and mobile development. Roles: ERP Developer · DevOps Engineer · Software Engineer · Full-Stack Web Developer Contact: matthewswong2610@gmail.com GitHub: https://github.com/matthews-wong LinkedIn: https://www.linkedin.com/in/matthewswong ## Machine-Readable Resources - Full version (with article summaries): https://www.matthewswong.com/llms-full.txt - RSS feed: https://www.matthewswong.com/feed.xml - JSON feed: https://www.matthewswong.com/feed.json - Sitemap: https://www.matthewswong.com/sitemap.xml - Any page as Markdown: request its URL with `Accept: text/markdown` ## Developers: Matthews Wong API - [Developer guide](https://www.matthewswong.com/en/developers/): quickstart, endpoints, error codes, versioning and deprecation policy, sandbox - API description (OpenAPI 3.1): https://www.matthewswong.com/openapi.json - API index (v1): https://www.matthewswong.com/api/v1/ - API catalog (RFC 9727): https://www.matthewswong.com/.well-known/api-catalog ## Core Expertise - ERP Systems: ERP module development (AP/AR, approvals, inventory, HR), implementation, customisation vs configuration, data migration, SAP/Oracle API integration, digital transformation - DevOps & Cloud Infrastructure: CI/CD (GitHub Actions, ArgoCD), Docker, Kubernetes, Terraform, Ansible, AWS, Google Cloud Platform, observability (Prometheus, Grafana, Loki) - Full-Stack Web Development: Next.js, React, TypeScript, Node.js, NestJS, PostgreSQL, REST & GraphQL APIs ## Main Pages - [Home](https://www.matthewswong.com/en): Overview of skills, products, commercial projects, and workflow - [About](https://www.matthewswong.com/en/about): Who Matthews Wong is — a software engineer in Tangerang, Indonesia working across DevOps and cloud infrastructure, ERP systems and web development; career story, education (GPA 3.82, Magna Cum Laude), products, FAQ and a 24-second motion film - [Experience](https://www.matthewswong.com/en/experience): Work history — AI Forward Deployed Engineer at Commsult APAC (Oct 2026 - Present); DevOps & Infrastructure Engineer at Commsult APAC (Jul 2026 - Oct 2026); DevOps Engineer at Commsult APAC (Sep 2025 - Jul 2026); DevOps Engineer (Intern) at Commsult APAC (Jan 2025 - Sep 2025); Software Development Engineer in Test at Commsult APAC (Jul 2024 - Jan 2025); Project-Based Virtual Intern : Data Scientist x Rakamin Academy at id/x partners (May 2024 - Jun 2024); Project-Based Virtual Intern : Mobile Apps Developer x Rakamin Academy at PT Bank Mandiri (Persero) Tbk (Jan 2024 - Feb 2024) - [Projects](https://www.matthewswong.com/en/projects): Portfolio of ERP, engineering, and commercial projects - [Case Studies](https://www.matthewswong.com/en/case-studies): Real engineering case studies with outcomes - [Education](https://www.matthewswong.com/en/education): Swiss German University, Information Technology - [Certifications](https://www.matthewswong.com/en/certifications): Professional certifications including PagerDuty DevOps Professional Certificate - [Hackathons](https://www.matthewswong.com/en/hackathons): Competition participation including PwC Capture The Flag - [Blog](https://www.matthewswong.com/en/blog): 636+ technical articles on DevOps, Cloud, ERP, AI, and software engineering - [Contact](https://www.matthewswong.com/en/contact): Get in touch form and direct contact details ## Projects - [ANCoraPRO](https://www.matthewswong.com/en/projects/ancorapro): Finance ERP — AP/AR, Hierarchical Approvals & Email Automation - [AI Feeds](https://www.matthewswong.com/en/projects/ai-feeds): Curated AI repository discovery — anti doom-scrolling - [Review CI](https://www.matthewswong.com/en/projects/review-ci): CI/CD pipeline analyzer with actionable insights - [Jakarta Intl Denso](https://www.matthewswong.com/en/projects/jakarta-intl-denso): Car care workshop website — local SEO & visibility - [Parcel Cirebon](https://www.matthewswong.com/en/projects/parcel-cirebon): Gift parcel storefront — catalogue, seasonal SEO & chat ordering - [TikTok Agency Incubator](https://www.matthewswong.com/en/projects/tiktok-agency-incubator): Official TikTok campaign web app — agency-speed delivery - [Shibui Matcha Bar](https://www.matthewswong.com/en/projects/shibui-matcha-bar): Café landing page — brand identity & organic growth - [MPilates Website](https://www.matthewswong.com/en/projects/mpilates): Pilates studio website — class showcase & WhatsApp booking - [STADPASS](https://www.matthewswong.com/en/projects/stadpass): Stadium indoor navigation app using BLE beacons - [Observer KPU](https://www.matthewswong.com/en/projects/observer-kpu): AI-powered election news platform with LLM chatbot - [Credit Risk Analysis](https://www.matthewswong.com/en/projects/credit-risk-analysis): XGBoost predictive model for financial risk classification - [Security Onion Lab](https://www.matthewswong.com/en/projects/security-onion-lab): Network threat detection with automated Discord alerting ## Blog — DevOps & Cloud Infrastructure - [AWS Bedrock AgentCore Guide: Runtime, Gateway, Memory, Policy](https://www.matthewswong.com/en/blog/aws-bedrock-agentcore-guide): AWS Bedrock AgentCore guide: Runtime, harness, Gateway, Memory and Policy, plus deploying an OpenAI Agents SDK agent and region notes for Indonesia. - [Codex SDK Tutorial: Automate Coding Tasks in TypeScript](https://www.matthewswong.com/en/blog/codex-sdk-typescript-automation): Codex SDK tutorial in TypeScript: start and resume threads, set sandbox modes, stream events and run Codex in GitHub Actions to triage failing tests. - [Easypanel vs Coolify vs Dokploy: Self-Hosted PaaS on a VPS](https://www.matthewswong.com/en/blog/easypanel-vs-coolify-vs-dokploy): Easypanel vs Coolify vs Dokploy compared: a commercial panel with a free plan against two open-source PaaS tools on licence, pricing, backups and lock-in. - [OpenTelemetry GenAI Semantic Conventions: Agent Spans in Tempo](https://www.matthewswong.com/en/blog/opentelemetry-genai-agent-spans-tracing): OpenTelemetry GenAI semantic conventions for AI agents: map OpenAI Agents SDK traces to invoke_agent, chat and execute_tool spans and query them in Tempo. - [Reading Production Logs Without SSH on a Managed PaaS](https://www.matthewswong.com/en/blog/reading-production-logs-without-ssh): Reading production logs without SSH on a managed PaaS: structured JSON logging, correlation IDs, stdout buffering traps, and the pre-incident checklist. - [Zero-Downtime Schema Migrations on a Kubernetes Rolling Deploy](https://www.matthewswong.com/en/blog/zero-downtime-migration-rolling-deploy): On a rolling deploy two releases share one schema. The overlap window, the migration job that must not run per replica, and why rollback decides the plan. - [Build Gates: Architecture Rules a README Cannot Enforce](https://www.matthewswong.com/en/blog/build-gates-architecture-rules-ci): How I turned three architecture rules into prebuild gates that fail the build, what each one cost, and the parity check that hid 168 wrong dates. - [Docker Build Cache: Faster PaaS Deploys From a Cold Builder](https://www.matthewswong.com/en/blog/docker-build-cache-paas-deploy-speed): Why a PaaS deploy is slow when the build is short: Docker layer ordering, .dockerignore, BuildKit cache mounts and registry cache on a cold builder. - [Claude Code Plugin Upgrades: Version Pinning and Rollback](https://www.matthewswong.com/en/blog/claude-code-plugin-rollback-version-pinning): A Claude Code plugin upgrade changes how the agent behaves, not whether the build passes. Version pinning, detecting a moved tag, and rolling one back. - [Claude Code Plugin Release Automation in GitHub Actions](https://www.matthewswong.com/en/blog/claude-code-plugin-ci-release-automation): A GitHub Actions pipeline for a Claude Code plugin release: validate the manifest strictly, gate on behaviour, tag on a clean tree, then publish. - [AI DevOps Assistants for Kubernetes Production Triage](https://www.matthewswong.com/en/blog/ai-devops-assistant-production-triage): What an AI DevOps assistant really shortens in Kubernetes triage, the exit codes it should not decide for you, and the faults that never reach your logs. - [Self-Host n8n and Flowise in IDR: What One-Click Deploy Skips](https://www.matthewswong.com/en/blog/one-click-n8n-flowise-self-host-idr): Self-hosting n8n and Flowise on an IDR-billed PaaS takes one click. The persistent volume, webhook URL, encryption key and auth are still yours to set. - [How a PaaS Build Engine Auto-Writes Your Dockerfile](https://www.matthewswong.com/en/blog/helipack-auto-dockerfile-build-engine): Inside a PaaS build engine: the repository signals that decide your Dockerfile, the four cases auto-detection gets wrong, and a hand-written override. - [Claude Code Environment Variables That Actually Matter](https://www.matthewswong.com/en/blog/claude-code-env-vars-reference-guide): Claude Code reads dozens of environment variables. Here are the ones worth setting on a build agent, and the three with side effects you did not want. - [Claude Code OpenTelemetry: Metrics, Events and Cost](https://www.matthewswong.com/en/blog/claude-code-analytics-otel-monitoring): Six environment variables give you per-user cost, token and tool telemetry. Here are the metrics worth alerting on and the content logging to weigh. - [Claude Code Network Config: Proxies, mTLS and Domains](https://www.matthewswong.com/en/blog/claude-code-network-config-proxy-firewall): The allowlist behind a working Claude Code install, why background agents miss your shell exports, and the one setting validated at startup. - [Claude Code Dev Containers: Isolation That Holds](https://www.matthewswong.com/en/blog/claude-code-devcontainer-setup): A dev container gives Claude Code a bounded environment. Here is the auth that survives rebuilds, the egress firewall, and what isolation misses. - [Claude Code in GitLab CI/CD: Jobs, OIDC and MRs](https://www.matthewswong.com/en/blog/claude-code-gitlab-ci-cd-integration): Running Claude Code in GitLab CI is one job and one masked variable. The mention trigger, the PATH trap and the OIDC setup are where teams actually stall. - [Claude Code Scheduled Tasks: Loops, Cron and Routines](https://www.matthewswong.com/en/blog/claude-code-scheduled-tasks-routines): Three ways to schedule Claude Code work, the jitter that moves your fire times, and the seven-day expiry that stops a forgotten loop running forever. - [Claude Code Self-Hosted Runners: Cloud Sessions, Your Box](https://www.matthewswong.com/en/blog/claude-code-self-hosted-runners-guide): Self-hosted environments run Claude Code cloud sessions inside your network with no inbound ports. Here is the lifecycle, sizing rule and exclusions. - [Running the Hermes Agent as an Autonomous Coder on a VPS](https://www.matthewswong.com/en/blog/hermes-agent-autonomous-coding-vps-setup): A hardened container, cron workstreams, credentials that survive a sanitised environment, and the watchdog that keeps an unattended coding agent alive. - [A Deterministic Merge Gate for a Self-Merging AI Agent](https://www.matthewswong.com/en/blog/autonomous-agent-merge-gate-hook): Let an agent merge its own pull requests safely: a pre-tool hook that blocks the merge when the test count dropped or tests were skipped to go green. - [Debugging a Production VPS Incident With Claude Code](https://www.matthewswong.com/en/blog/claude-code-production-incident-debugging): Use an AI agent during an incident without making it worse: evidence before hypotheses, test the origin not the CDN, and hooks that block destruction. - [AI Code Review Tools Compared for 2026](https://www.matthewswong.com/en/blog/ai-code-review-tools-compared): The best AI code review tools for 2026: terminal agents, platform pull request bots, and dedicated services, and how to pick the right one for your team. - [Parallel Claude Code Agents With Git Worktrees](https://www.matthewswong.com/en/blog/claude-code-parallel-agents-git-worktrees): Run parallel Claude Code agents with git worktrees: isolate each session's files, avoid port and database collisions, and know when parallelism pays off. - [Claude Code GitHub Actions: Issue to Merged PR](https://www.matthewswong.com/en/blog/claude-code-github-actions-guide): How Claude Code GitHub Actions turns an @claude mention into a reviewable pull request: install the app, scope its secrets, and keep review on merge. - [Claude Code Headless Mode for CI/CD Pipelines](https://www.matthewswong.com/en/blog/claude-code-headless-mode-ci-guide): How Claude Code headless mode works: run the agent with claude -p in CI/CD, restrict its tools, parse JSON output, and gate on the exit code. - [Helm 4 Migration Guide: What's New and How to Upgrade](https://www.matthewswong.com/en/blog/helm-4-migration-guide): Helm 4 is the first major release since 2019. Learn the real breaking changes — server-side apply, plugin system, registry login — and how to migrate. - [Load Testing Node.js APIs with k6 and Grafana Dashboards](https://www.matthewswong.com/en/blog/k6-load-testing-nodejs-grafana): How I load test Node.js APIs with k6 and Grafana: writing tests, VUs and stages, thresholds as CI gates, and finding the DB connection-pool ceiling. - [Podman Quadlets: Replace Docker Compose with systemd](https://www.matthewswong.com/en/blog/podman-quadlets-replace-docker-compose): How I replaced Docker Compose with Podman Quadlets: rootless .container systemd units with auto-restart, boot ordering, journald logs, and auto-update. - [KEDA: Event-Driven Autoscaling & Scale-to-Zero on K8s](https://www.matthewswong.com/en/blog/keda-event-driven-autoscaling-kubernetes): How I autoscale Kubernetes with KEDA on queue depth, Kafka lag, Prometheus, and cron instead of CPU, with scale-to-zero for cost and cold-start trade-offs. - [Kubernetes In-Place Pod Resize: CPU & Memory No Restart](https://www.matthewswong.com/en/blog/kubernetes-in-place-pod-resize): Resize CPU and memory on running Kubernetes pods without a restart. How the resize subresource, resizePolicy, and VPA InPlaceOrRecreate work at v1.35 GA. - [kubectl debug: Fix CrashLoopBackOff & Distroless Pods](https://www.matthewswong.com/en/blog/kubectl-debug-crashloopbackoff-distroless): How I debug Kubernetes pods with kubectl debug and ephemeral containers when kubectl exec fails on CrashLoopBackOff and shell-less distroless pods. - [Prometheus 3.0: OTLP, Native Histograms, UTF-8 & New UI](https://www.matthewswong.com/en/blog/prometheus-3-0-whats-new): Prometheus 3.0 is the first major release in seven years: a redesigned UI, native OTLP ingestion, Remote Write 2.0, UTF-8 names, and 2.x upgrade traps. - [uv: The Fast Rust Python Package Manager Replacing pip](https://www.matthewswong.com/en/blog/uv-python-package-manager-rust): uv is an extremely fast Rust-based Python package and project manager that is 10-100x faster than pip and replaces pip, poetry, pyenv, and virtualenv. - [Kubernetes Native Sidecar Containers: A Practical Guide](https://www.matthewswong.com/en/blog/kubernetes-native-sidecar-containers): How Kubernetes native sidecar containers work as init containers with restartPolicy Always, fixing Job completion and shutdown ordering, stable in v1.33. - [Feature Flags for Trunk-Based Development in DevOps](https://www.matthewswong.com/en/blog/feature-flag-driven-trunk-based-development): How feature flags power trunk-based development: decouple deploy from release, use kill switches, keep short-lived branches, and manage flag hygiene. - [GitHub Actions Reusable Workflows vs Composite Actions Guide](https://www.matthewswong.com/en/blog/github-actions-reusable-workflows-composite-actions): Learn when to use GitHub Actions reusable workflows vs composite actions, how to pass inputs and secrets, and cut CI duplication across many repos. - [Autoscaling GitHub Actions Runners on Kubernetes with ARC](https://www.matthewswong.com/en/blog/github-actions-runner-autoscaling-arc): Autoscale ephemeral GitHub Actions self-hosted runners on Kubernetes with ARC: queue-driven scaling, scale-to-zero, container modes, and real cost control. - [Incus/LXC System Containers vs Docker: When to Use Each](https://www.matthewswong.com/en/blog/incus-lxc-system-containers-vs-docker): Incus/LXC system containers run a persistent full OS sharing the host kernel. Learn when they beat Docker application containers and VMs, with a comparison table. - [Kubernetes Gateway API vs Ingress: The Successor Explained](https://www.matthewswong.com/en/blog/kubernetes-gateway-api-vs-ingress): How the Kubernetes Gateway API replaces Ingress with role-oriented GatewayClass, Gateway, and HTTPRoute resources, plus a practical migration path off ingress-nginx. - [restic vs BorgBackup: Encrypted Deduplicated Backups Guide](https://www.matthewswong.com/en/blog/restic-vs-borg-encrypted-backups): Compare restic vs BorgBackup for encrypted, deduplicated backups: repositories, S3 and SFTP backends, prune and retention policy, and restore speed. - [k6 SLO Quality Gate for Bitbucket Pipelines CI/CD](https://www.matthewswong.com/en/blog/slo-quality-gate-bitbucket-pipeline): How I added a k6 smoke-test SLO gate to a Bitbucket Pipelines release stage, automatically blocking performance regressions before they reach production. - [Argo Rollouts Canary & Blue-Green Progressive Delivery](https://www.matthewswong.com/en/blog/argo-rollouts-progressive-delivery-canary): A hands-on guide to Argo Rollouts progressive delivery: canary and blue-green strategies, Prometheus analysis templates, and automated rollback on SLO breach. - [Docker Buildx Bake: Declarative Multi-Platform Builds](https://www.matthewswong.com/en/blog/docker-bake-multi-platform-builds): Use docker buildx bake and an HCL file for declarative multi-platform image builds — matrix targets, scoped caching, and a clean GitHub Actions CI workflow. - [OpenTofu vs Terraform: Migration Guide After BSL](https://www.matthewswong.com/en/blog/opentofu-vs-terraform-migration): OpenTofu vs Terraform after the license change: compatibility, state file caveats, registry differences, and the exact commands to migrate a project safely. - [Prometheus remote_write to Grafana Mimir at Scale](https://www.matthewswong.com/en/blog/prometheus-remote-write-mimir-scaling): Configure Prometheus remote_write to Grafana Mimir for horizontally scalable long-term storage: blocks storage, tenants, and faster PromQL queries. - [Terraform Import Blocks: Bring Existing Infra Under IaC](https://www.matthewswong.com/en/blog/terraform-import-blocks-existing-infra): Use Terraform import blocks and -generate-config-out to bring existing infrastructure under IaC without hand-writing every resource. Real workflow and gotchas. - [Grafana Alloy Migration from Promtail and Agent Guide](https://www.matthewswong.com/en/blog/grafana-alloy-opentelemetry-collector-migration): Migrate to Grafana Alloy from Promtail and Grafana Agent: the OpenTelemetry Collector-compatible components, the alloy convert command, and Alloy config syntax. - [Postgres Row-Lock Bottleneck via Prometheus + InfluxDB](https://www.matthewswong.com/en/blog/postgres-row-lock-bottleneck-prometheus-influxdb): How dual-backend observability with Prometheus and InfluxDB helped localize a Postgres row-lock bottleneck, from pg_stat_activity to pg_locks. - [OpenTelemetry Collector: Designing a Telemetry Pipeline](https://www.matthewswong.com/en/blog/opentelemetry-collector-pipeline-design): Design a production-ready OpenTelemetry Collector pipeline: receivers, processors, tail-based sampling, batching, and exporting traces to any backend. - [I Self-Hosted Headscale for a Tailscale Mesh VPN Homelab](https://www.matthewswong.com/en/blog/tailscale-mesh-vpn-self-hosted): Set up a Tailscale mesh VPN with WireGuard for servers and a homelab, add ACLs and subnet routers, then self-host Headscale for full control. - [Building a Custom CPU Autoscaler for Docker Swarm](https://www.matthewswong.com/en/blog/docker-swarm-custom-autoscaler-cpu): Docker Swarm has no Kubernetes-style HPA, so during my thesis I built a Bash daemon with streak consensus and cooldown to autoscale on CPU load. - [Renovate: Automated Dependency Updates for DevOps Teams](https://www.matthewswong.com/en/blog/renovate-automated-dependency-updates): Configure Renovate for automated dependency updates: grouping rules, automerge policies, scheduling, and lockfile maintenance to cut PR noise. - [VictoriaMetrics vs Prometheus for Long-Term Metrics](https://www.matthewswong.com/en/blog/victoriametrics-vs-prometheus-long-term): VictoriaMetrics vs Prometheus for long-term metric retention: compare storage efficiency, memory use, MetricsQL, and a safe remote write migration path. - [Docker Swarm Replicas vs Throughput: A Load Testing Case Study](https://www.matthewswong.com/en/blog/docker-swarm-load-testing-replicas-throughput): k6 load tests on Docker Swarm show doubling replicas cuts latency but barely lifts throughput, since PostgreSQL row locking is the real bottleneck. - [Prometheus Cardinality: Recording Rules That Save Your TSDB](https://www.matthewswong.com/en/blog/prometheus-recording-rules-cardinality): Prometheus recording rules pre-aggregate high-cardinality metrics, cutting TSDB memory pressure and speeding up PromQL dashboards and alerts at scale. - [Distroless Docker Images: Smaller, Safer Containers](https://www.matthewswong.com/en/blog/docker-distroless-image-optimization): Cut Docker image size and CVE surface with distroless base images and multi-stage builds, plus how to debug containers that have no shell at all. - [GitHub Actions OIDC: Keyless Cloud Auth for CI/CD](https://www.matthewswong.com/en/blog/github-actions-oidc-keyless-cloud-auth): Replace long-lived AWS and GCP keys with GitHub Actions OIDC federation, covering trust policies, subject claims, and common misconfigurations in CI/CD. - [Kamal 2: Zero-Downtime Docker Deploys Without Kubernetes](https://www.matthewswong.com/en/blog/kamal-2-docker-deployment-guide): Deploy Docker containers to any VPS with Kamal 2: kamal-proxy zero-downtime rollouts, Postgres and Redis accessories, secrets, and instant rollback. - [Coolify vs Dokploy: Self-Hosted PaaS for VPS Deployment](https://www.matthewswong.com/en/blog/coolify-vs-dokploy-self-hosted-paas): Coolify and Dokploy both turn a bare VPS into a self-hosted PaaS. This hands-on comparison covers architecture, database backups, and git deploys. - [Dokploy: Self-Hosted PaaS on Your Own VPS with Docker](https://www.matthewswong.com/en/blog/dokploy-self-hosted-paas-vps): Run Dokploy as a Heroku-style self-hosted PaaS on a single VPS: Docker Swarm internals, app and database deploys, Traefik routing, and automated backups. - [Docker BuildKit Cache Mounts: Cut CI Build Times in Half](https://www.matthewswong.com/en/blog/docker-buildkit-cache-mounts-faster-builds): Speed up Docker builds in CI using BuildKit cache mounts for npm, apt, pip, and Go dependencies — plus GitHub Actions and GitLab registry cache exports. - [Controlling Docker From Your Backend: dockerode and the Socket](https://www.matthewswong.com/en/blog/docker-daemon-socket-backend-control): Learn how to control Docker from a Node.js backend using dockerode — list, create, and start containers, plus the security risks of the Docker socket. - [Practical 3-2-1 Backups for VPSs with Restic and Object Storage](https://www.matthewswong.com/en/blog/backup-3-2-1-strategy-vps): Implement the 3-2-1 backup rule on a VPS with restic: encrypted S3-compatible repositories, correct database dumps, retention, verification, and restore drills. - [What cgroups v2 Really Does When You Set Docker Memory Limits](https://www.matthewswong.com/en/blog/linux-cgroups-container-resource-limits): How Docker --memory and --cpus map to cgroups v2 memory.max and cpu.max, why the OOM killer fires with exit 137, CPU throttling, and a sizing procedure that works. - [Blue-Green vs Canary Deployments on a Budget (No Kubernetes)](https://www.matthewswong.com/en/blog/blue-green-vs-canary-on-budget): Blue-green and canary deployments without Kubernetes: nginx upstreams, Docker Compose, weighted canaries, expand-and-contract migrations, and a decision rule for small teams. - [Uptime Kuma: Self-Hosted Uptime Monitoring That Just Works](https://www.matthewswong.com/en/blog/self-hosted-uptime-kuma-monitoring): How to run Uptime Kuma as a self-hosted uptime monitor: Docker setup, WebSocket reverse proxy, keyword and heartbeat monitors, status pages, and production pitfalls. - [GitHub Actions Caching Strategies That Actually Cut CI Minutes](https://www.matthewswong.com/en/blog/github-actions-caching-strategies): Practical GitHub Actions caching: setup-node and restore-keys, BuildKit type=gha vs registry Docker layer caches, the 10 GB and 7-day limits, and a 30-minute audit. - [Platform Engineering: Building an Internal Developer Platform](https://www.matthewswong.com/en/blog/platform-engineering-internal-developer-platform): Build an Internal Developer Platform with Backstage, DORA metrics, and Team Topologies. Practical guide to self-service infrastructure and service catalogs. - [Caddy vs Nginx for Automatic HTTPS: When Each One Wins](https://www.matthewswong.com/en/blog/caddy-vs-nginx-automatic-https): Caddy vs Nginx compared for automatic HTTPS: in-process ACME renewal and CA failover vs certbot timers, tuning depth, and ecosystem — with a safe migration plan. - [Docker Compose Watch: Instant Feedback for Local Container Dev](https://www.matthewswong.com/en/blog/docker-compose-watch-local-dev): How Docker Compose Watch replaces bind mounts with sync, rebuild, and sync+restart rules for a sub-two-second local dev feedback loop in containers. - [k3s Kubernetes for Indonesian Startups: Production on Budget VPS](https://www.matthewswong.com/en/blog/kubernetes-k3s-production-lightweight-indonesia): Deploy a production k3s Kubernetes cluster on Indonesian VPS for under Rp 600k/month. Covers installation, Longhorn storage, TLS ingress, CI/CD, and monitoring. - [FinOps for Indonesian Cloud Teams: A Practical Cost Optimization Guide](https://www.matthewswong.com/en/blog/finops-cloud-cost-optimization-indonesia): Cut AWS and GCP cloud waste in Indonesian deployments: find unattached EBS, detect cost anomalies with Python, right-size instances, and schedule dev shutdowns for 65% savings. - [Indonesia PDN: Developer Guide to Government Cloud Migration](https://www.matthewswong.com/en/blog/pusat-data-nasional-pdn-cloud-developer-guide): Complete developer guide to Indonesia's PDN national data centers: regulatory framework (PP 71/2019), SPBE integration, security classification tiers, Terraform IaC patterns, and migration checklist. - [Free Custom Email: Cloudflare Routing + SMTP2Go](https://www.matthewswong.com/en/blog/cloudflare-email-inbound-smtp2go): Set up free custom domain email with Cloudflare Email Routing for inbound and SMTP2Go for outbound SMTP. Step-by-step setup guide for developers. - [Google Cloud vs DigitalOcean: A Practical Guide for Side-Project Developers](https://www.matthewswong.com/en/blog/google-cloud-vs-digital-ocean): A hands-on comparison of Google Cloud and DigitalOcean from a developer who runs production workloads on both — covering pricing, managed services, and when to use each. - [Grafana + Prometheus Monitoring Stack for Your VPS: Complete Setup Guide](https://www.matthewswong.com/en/blog/grafana-prometheus-monitoring-vps): Set up a production-grade Grafana and Prometheus monitoring stack on a VPS using Docker Compose, with Node Exporter, alerting via Telegram, and real PromQL dashboards. - [Zero-Downtime Deployments with NGINX Blue-Green on a Single VPS](https://www.matthewswong.com/en/blog/zero-downtime-nginx-blue-green-deploy): Implement blue-green deployments on a single VPS using NGINX and Docker — swap live traffic between two containers with a shell script and achieve true zero-downtime releases. - [Automate SSL Certificate Renewal with Certbot and NGINX](https://www.matthewswong.com/en/blog/automate-ssl-certbot-nginx): Set up automatic HTTPS with Certbot and Let's Encrypt on Ubuntu, configure NGINX as a TLS terminator, and never manually renew an SSL certificate again. - [Self-Hosted Observability Stack on DigitalOcean: Metrics, Logs, and Alerts](https://www.matthewswong.com/en/blog/self-hosted-observability-digital-ocean): Build a complete self-hosted observability platform on a single DigitalOcean Droplet — Prometheus metrics, Loki log aggregation, Grafana dashboards, and Telegram alerting for under $25/month. - [Kubernetes for the Solo Developer: A Practical GKE Guide Without the Overhead](https://www.matthewswong.com/en/blog/kubernetes-solo-developer-guide): A pragmatic guide to running production Kubernetes on GKE Autopilot as a solo developer — avoiding common pitfalls, minimizing cost, and setting up a CI/CD pipeline that actually works. - [The Docker Workflow I Use on Every Project](https://www.matthewswong.com/en/blog/docker-workflow-every-project): A practical, battle-tested Docker setup using multi-stage builds and Compose that I apply to every NestJS and Next.js project from day one. - [Google Cloud Managed Services vs Raw Compute: When to Use Which](https://www.matthewswong.com/en/blog/google-cloud-managed-services-vs-raw-compute): A practical decision framework for choosing between Cloud Run, GKE, Cloud SQL, and raw Compute Engine VMs—based on real workloads rather than marketing copy. - [Event-Driven Architecture with Kafka and NestJS: A Production Guide](https://www.matthewswong.com/en/blog/event-driven-kafka-nestjs): How to build a robust event-driven system using Apache Kafka and NestJS — from topic design to consumer groups, error handling, and production tuning. - [gRPC vs REST for Internal Microservices APIs: A Practical Comparison](https://www.matthewswong.com/en/blog/microservices-grpc-vs-rest-internal): A data-driven comparison of gRPC and REST for internal service-to-service communication — with benchmarks, NestJS examples, and an honest guide to when each is the right choice. - [PostgreSQL Sharding Strategy: When and How to Scale Your Database](https://www.matthewswong.com/en/blog/postgresql-sharding-strategy): A pragmatic guide to PostgreSQL sharding and partitioning — covering table partitioning, Citus distributed tables, and the honest truth about when you actually need to shard. - [Message Queues in Node.js: RabbitMQ vs BullMQ — Which Should You Choose?](https://www.matthewswong.com/en/blog/message-queue-rabbitmq-bullmq): A practical comparison of RabbitMQ and BullMQ for Node.js backend systems — covering architecture, use cases, NestJS integration, and when each is the right tool. - [API Gateway Pattern with NestJS: Routing, Auth, and Rate Limiting in Production](https://www.matthewswong.com/en/blog/api-gateway-pattern-nestjs-guide): How to implement an API gateway in NestJS microservices — covering request routing, authentication aggregation, rate limiting, and the trade-offs of building vs buying. - [Distributed Tracing with OpenTelemetry: A Practical NestJS Implementation](https://www.matthewswong.com/en/blog/distributed-tracing-opentelemetry): How to instrument a NestJS microservices application with OpenTelemetry for end-to-end distributed tracing — covering auto-instrumentation, custom spans, and backend choices. - [Circuit Breaker Pattern in NestJS: Building Resilient Microservices](https://www.matthewswong.com/en/blog/circuit-breaker-nestjs-pattern): How to implement the circuit breaker pattern in NestJS using nestjs-resilience4j or a custom implementation — preventing cascading failures and building self-healing services. - [CQRS and Event Sourcing with NestJS: When Complexity is Worth It](https://www.matthewswong.com/en/blog/cqrs-event-sourcing-nestjs): A practical guide to CQRS and event sourcing in NestJS — what the patterns actually solve, how to implement them with @nestjs/cqrs, and Martin Fowler's honest warning about when to skip them. - [Scaling WebSockets with Redis Pub/Sub: From One Server to Many](https://www.matthewswong.com/en/blog/websocket-scaling-redis-pubsub): How to horizontally scale a WebSocket server using Redis Pub/Sub and Socket.IO — covering the sticky session problem, Redis adapter setup, and what happens when Redis becomes the bottleneck. - [OWASP Top 10 Developer Checklist: What I Actually Implement](https://www.matthewswong.com/en/blog/owasp-top-10-developer-checklist): A practical OWASP Top 10 2021 checklist from a developer who hardens production systems — covering real CVEs, code-level mitigations, and what actually gets exploited. - [JWT vs Session Authentication in Production: What I Actually Use](https://www.matthewswong.com/en/blog/jwt-vs-session-auth-production): An honest comparison of JWT and session-based authentication for production APIs — covering security trade-offs, revocation, storage, and what I implement for ERP systems. - [SQL Injection Prevention with ORMs: Why Prisma and TypeORM Still Need Your Help](https://www.matthewswong.com/en/blog/sql-injection-orm-prevention): ORMs prevent most SQL injection but not all — learn the raw query pitfalls, Prisma safe patterns, and the real-world injection scenarios I test for in every ERP system. - [CORS Configuration for Next.js and NestJS: Getting It Right in Production](https://www.matthewswong.com/en/blog/cors-configuration-nextjs-nestjs): Properly configuring CORS for Next.js frontends and NestJS APIs — covering origins, credentials, preflight caching, and the misconfigurations that create real security holes. - [HTTPS and TLS Beyond Certbot: Hardening Your SSL Configuration](https://www.matthewswong.com/en/blog/https-tls-beyond-certbot): Go beyond basic Let's Encrypt setup — HSTS preloading, TLS 1.3, OCSP stapling, cipher suite hardening, and the SSL misconfigurations I find on production servers. - [API Security in NestJS Production: The Controls I Actually Deploy](https://www.matthewswong.com/en/blog/api-security-nestjs-production): Practical NestJS API security — rate limiting, input validation, security headers, audit logging, and the specific controls I configure for every production API deployment. - [Secret Scanning and Preventing Credentials Leaks in GitHub](https://www.matthewswong.com/en/blog/secret-scanning-github-prevention): How to prevent secrets from entering your git history — pre-commit hooks, GitHub Secret Scanning, gitleaks, and what to do when you have already committed credentials. - [Docker Container Security Scanning with Trivy: A Production Guide](https://www.matthewswong.com/en/blog/docker-container-security-scanning): Integrate Trivy container vulnerability scanning into your Docker workflow — covering CI/CD integration, base image selection, and reducing your container attack surface. - [Penetration Testing Basics for Developers: What I Learned from PwC CTF](https://www.matthewswong.com/en/blog/penetration-testing-developer-basics): A developer's introduction to penetration testing — the tools, methodologies, and mindset I took away from competing in PwC's Capture the Flag security competition. - [Nginx vs Traefik: Choosing the Right Reverse Proxy for Your Stack](https://www.matthewswong.com/en/blog/nginx-vs-traefik): A practical comparison of Nginx and Traefik as reverse proxies — covering performance, auto-discovery, Docker integration, and when each tool actually makes sense. - [Linux Server Hardening Checklist: What I Do on Every Fresh VPS](https://www.matthewswong.com/en/blog/linux-server-hardening): A practical Linux server hardening checklist covering SSH lockdown, firewall rules, automatic updates, and fail2ban — steps I apply to every DigitalOcean and GCP instance. - [GitHub Actions vs GitLab CI: Which CI/CD Platform Should You Choose?](https://www.matthewswong.com/en/blog/github-actions-vs-gitlab): A real-world comparison of GitHub Actions and GitLab CI/CD covering pricing, runner performance, YAML syntax, and when each platform makes more sense for your team. - [PostgreSQL vs MySQL in Production: Which Database Should You Choose?](https://www.matthewswong.com/en/blog/postgresql-vs-mysql): A developer's honest comparison of PostgreSQL and MySQL for production use — covering performance benchmarks, licensing, JSON support, and why PostgreSQL is now the default choice. - [Redis Caching Patterns for NestJS: From 450ms to 42ms API Response Times](https://www.matthewswong.com/en/blog/redis-caching-nestjs): Practical Redis caching patterns for NestJS — cache-aside, write-through, and cache invalidation strategies with real code examples and performance measurements. - [Docker Compose vs Kubernetes for Small Teams: When to Use Each](https://www.matthewswong.com/en/blog/docker-compose-vs-k8s): A practical guide for small teams deciding between Docker Compose and Kubernetes — covering complexity, cost, and the right progression from one to the other. - [Monitoring and Alerting for Solo DevOps: A Practical Stack That Works](https://www.matthewswong.com/en/blog/monitoring-alerting-solo): How to set up monitoring and alerting as a solo DevOps engineer — Prometheus, Grafana, Uptime Kuma, and Telegram alerts without the enterprise complexity. - [SSH Security Hardening for VPS: Stop the Brute Force Before It Starts](https://www.matthewswong.com/en/blog/ssh-security-hardening): A practical SSH hardening guide for VPS owners — disable password auth, change ports, configure fail2ban, and lock down sshd_config before your server gets compromised. - [PostgreSQL Backup Strategy for VPS: From pg_dump to WAL Archiving](https://www.matthewswong.com/en/blog/postgresql-backup-strategy): A practical PostgreSQL backup strategy for VPS deployments — covering pg_dump, pg_basebackup, WAL archiving, and automated offsite backup with real configuration examples. - [Nginx Performance Tuning: From Default Config to 50,000 Req/s](https://www.matthewswong.com/en/blog/nginx-performance-tuning): A practical Nginx performance tuning guide covering worker processes, connections, kernel parameters, gzip, and caching — with real configuration you can apply today. - [Fail2ban on VPS: Automate Brute Force Protection in 15 Minutes](https://www.matthewswong.com/en/blog/fail2ban-vps-security): Set up fail2ban on Ubuntu VPS to automatically block SSH brute-force attacks, protect Nginx, and configure custom jails — with real configuration examples. - [Systemd Services for Background Jobs: The Right Way to Run Node.js in Production](https://www.matthewswong.com/en/blog/systemd-services-jobs): How to write production-ready systemd service files for Node.js, NestJS, and background workers — with restart policies, resource limits, and environment variable management. - [WireGuard VPN for Private Cloud Networking: Simple, Fast, Secure](https://www.matthewswong.com/en/blog/wireguard-vpn-cloud): How to set up WireGuard VPN to create a private overlay network between cloud servers and development machines — faster than OpenVPN with a fraction of the configuration. - [Log Rotation in Linux: Managing Production Logs Before They Fill Your Disk](https://www.matthewswong.com/en/blog/log-rotation-linux): How to configure logrotate for production Linux servers — preventing disk full outages, managing app logs, and setting up monitoring for log rotation health. - [Docker Secrets in Production: Stop Putting API Keys in Environment Variables](https://www.matthewswong.com/en/blog/docker-secrets-production): Why plain environment variables are not safe for Docker secrets, and how to use Docker secrets, external secret managers, and encrypted files to protect credentials in production. - [Cloud Run vs Cloud Functions: Which Google Serverless Platform Should You Use?](https://www.matthewswong.com/en/blog/cloud-run-vs-functions): A practical comparison of Cloud Run and Cloud Functions from real production deployments — covering cold starts, pricing, concurrency, and when each platform wins. - [Building Reusable Terraform Modules: A Production IaC Guide](https://www.matthewswong.com/en/blog/terraform-modules-reusable): How to design, structure, and version Terraform modules that your team can reuse across projects — with real patterns from production multi-environment deployments. - [Ansible Playbooks in Production: Real Automation Patterns That Scale](https://www.matthewswong.com/en/blog/ansible-playbooks-production): How to write, structure, and safely run Ansible playbooks for production server automation — with role-based organization, Vault secrets, and idempotency testing. - [How I Cut Cloud Costs by 40%: Real Optimization Strategies That Work](https://www.matthewswong.com/en/blog/cloud-cost-optimization): Practical cloud cost optimization techniques from actual production deployments — rightsizing, committed use discounts, storage tiering, and FinOps habits that stick. - [Multi-Cloud Strategy for Small Teams: Is It Worth the Complexity?](https://www.matthewswong.com/en/blog/multi-cloud-small-teams): An honest look at multi-cloud for small engineering teams — when it makes sense, when it does not, and how to manage two cloud providers without drowning in operational overhead. - [CDN with Cloudflare: How to Properly Serve Static Assets at the Edge](https://www.matthewswong.com/en/blog/cdn-cloudflare-static): A practical guide to configuring Cloudflare as a CDN for static assets — cache rules, TTLs, cache hit optimization, and tiered caching that actually cuts origin load. - [Nginx Load Balancer in Production: Configuration, Health Checks, and Failover](https://www.matthewswong.com/en/blog/load-balancer-production-config): A complete Nginx load balancer configuration guide for production — upstream groups, passive health checks, least-conn routing, SSL termination, and safe reload without downtime. - [Disaster Recovery Planning for VPS: Backups, RTO, and Actual Tested Recovery](https://www.matthewswong.com/en/blog/disaster-recovery-vps): A practical VPS disaster recovery plan with automated backups, defined RTO/RPO targets, and a recovery runbook you can actually execute when things go wrong at 2 AM. - [Container Registry Strategy on GCP: From GCR to Artifact Registry](https://www.matthewswong.com/en/blog/container-registry-gcr): Google shut down Container Registry on March 18, 2025. Here is how to migrate to Artifact Registry, set up vulnerability scanning, and build a proper Docker image management workflow. - [VPC Networking for Developers: A Practical Guide to Cloud Network Isolation](https://www.matthewswong.com/en/blog/vpc-networking-guide): Understand VPC networking concepts — subnets, routing tables, firewall rules, peering, and NAT — with practical examples for GCP and DigitalOcean deployments. - [Cloud Storage vs MinIO: Choosing Your Object Storage for Production](https://www.matthewswong.com/en/blog/cloud-storage-vs-minio): An honest comparison of managed cloud object storage (GCS, S3) versus self-hosted MinIO — covering cost, performance, operational overhead, and the licensing change that changes the calculus. - [GitHub Actions Self-Hosted Runners: Complete Setup and Security Guide](https://www.matthewswong.com/en/blog/github-actions-runners): How to set up, secure, and scale GitHub Actions self-hosted runners on your own VPS or GCP instance — with ephemeral mode, runner groups, and the security practices that matter. - [HashiCorp Vault for Production Secrets Management: Setup and Best Practices](https://www.matthewswong.com/en/blog/hashicorp-vault-secrets): How to deploy and configure HashiCorp Vault for production secrets management — dynamic credentials, audit logging, auto-unseal, and integrating with Kubernetes and CI/CD. - [Prometheus and AlertManager: Building an On-Call Alert System That Works](https://www.matthewswong.com/en/blog/prometheus-alertmanager): How to configure Prometheus AlertManager for production on-call alerting — routing trees, inhibition rules, grouping, Telegram integration, and high-availability setup. - [Elastic Stack (ELK) Self-Hosted: Production Setup and Operational Lessons](https://www.matthewswong.com/en/blog/elastic-stack-self-hosted): How to deploy and operate a self-hosted Elastic Stack for centralized logging — Elasticsearch cluster setup, Logstash pipelines, Kibana dashboards, and the operational pitfalls to avoid. - [Mastering Observability: Loki, Prometheus & Grafana](https://www.matthewswong.com/en/blog/loki-prometheus-observability): A comprehensive guide to implementing unified logging and metrics with Loki and Prometheus for Containerized observability. - [Cut GCS Egress Costs: Migrate to Cloudflare R2](https://www.matthewswong.com/en/blog/cloudflare-r2-gcs-egress): Migrate from Google Cloud Storage to Cloudflare R2 for zero egress costs. Step-by-step guide with real cost comparison numbers and migration scripts. - [DevSecOps: Integrating Security into CI/CD](https://www.matthewswong.com/en/blog/devsecops-security-pipeline): Shift security left with DevSecOps: SAST, DAST, dependency scanning, container image scanning, and secrets detection integrated into your CI/CD pipeline. - [SRE: SLOs, SLAs & Error Budgets Explained](https://www.matthewswong.com/en/blog/site-reliability-engineering-sre): Understand Site Reliability Engineering: define SLOs and SLAs, calculate error budgets, set up alerting policies, and balance reliability with feature velocity. - [GitOps with ArgoCD and Flux CD Explained](https://www.matthewswong.com/en/blog/gitops-argocd-flux): Implement GitOps with ArgoCD and Flux CD — declarative Kubernetes delivery where Git is the source of truth. Compare both with real setup examples. - [Infrastructure as Code with Terraform](https://www.matthewswong.com/en/blog/infrastructure-as-code-terraform): Manage cloud infrastructure declaratively with Terraform. Learn HCL syntax, state management, modules, and multi-cloud deployments with real examples. - [Ansible Infrastructure Automation Guide](https://www.matthewswong.com/en/blog/ansible-automation-infrastructure): Automate server provisioning, configuration management, and app deployment with Ansible. Real playbook examples for Node.js, Docker, and Nginx setups. - [Docker Swarm: Container Orchestration for Smaller Teams](https://www.matthewswong.com/en/blog/docker-swarm-orchestration): Docker Swarm vs Kubernetes: when Swarm wins, how to set up a multi-node cluster, deploy services, and manage rolling updates without the K8s complexity. - [Docker Best Practices for Production Containers](https://www.matthewswong.com/en/blog/docker-containerization-best-practices): Production-ready Docker practices: multi-stage builds, minimal base images, secrets management, health checks, and image optimization techniques. - [Kubernetes Deployment Strategies Explained](https://www.matthewswong.com/en/blog/kubernetes-deployment-strategies): Master Blue-Green, Canary, and Rolling deployments in Kubernetes. Learn when to use each strategy and how to implement them with real YAML examples. - [CI/CD with GitHub Actions: From Zero to Production](https://www.matthewswong.com/en/blog/ci-cd-pipeline-github-actions): Step-by-step guide to building a full CI/CD pipeline with GitHub Actions — automated tests, Docker builds, and zero-downtime deployments explained. ## Blog — Cloud - [Cloudflare Containers: 6x Faster Starts for Agent Sandboxes](https://www.matthewswong.com/en/blog/cloudflare-containers-agent-sandboxes): Cloudflare Containers start agent sandboxes in 648 ms median, pick image and instance at runtime and snapshot filesystems. What changed, what is missing. - [Indonesia Sovereign AI Data Centres: What Actually Changes](https://www.matthewswong.com/en/blog/indonesia-sovereign-ai-data-centre-impact): Indonesia sovereign AI data centres are real, but announced megawatts are not rentable capacity. What actually changes for a product shipping in 2026. - [Jakarta GPU Capacity: VRAM Sizing for Indonesian AI Teams](https://www.matthewswong.com/en/blog/jakarta-gpu-capacity-indonesian-ai-startups): Jakarta GPU capacity lands in 2028. What an Indonesian AI team can rent today, how to size VRAM and KV cache first, and what quantisation really costs. - [PaaS vs VPS in Indonesia: An Honest IDR Cost Breakdown](https://www.matthewswong.com/en/blog/paas-vs-vps-cost-indonesia-idr): Managed Indonesian PaaS vs a Jakarta VPS at matched 2 vCPU and 2 GB in real IDR, plus the hidden hours: patching, TLS renewal, tested backups and on-call. - [Kubernetes HPA Autoscaling: Surviving a PaaS Traffic Spike](https://www.matthewswong.com/en/blog/helipod-hpa-autoscaling-traffic-spike): Why Kubernetes HPA autoscaling on a managed PaaS does not serve the first seconds of a traffic spike: the 15-second sync period, cold pods and readiness. - [Jakarta vs Singapore PaaS Latency for Indonesian Users](https://www.matthewswong.com/en/blog/jakarta-vs-singapore-paas-latency): Why Singapore hosting costs Indonesian users real milliseconds: the fibre floor, the four round trips inside one HTTPS request, and how to measure them. - [Helipod Review: Deploying Next.js on an Indonesian PaaS](https://www.matthewswong.com/en/blog/helipod-paas-indonesia-nextjs-deploy): A close review of Helipod, the Indonesian PaaS: how Helipack builds Next.js with no Dockerfile, what Rupiah and QRIS billing cost, and its real limits. - [Helipod vs Dokploy: Managed PaaS or Self-Hosted VPS](https://www.matthewswong.com/en/blog/helipod-vs-dokploy-managed-vs-self-hosted): Helipod is a managed Indonesian PaaS billed in rupiah; Dokploy is a PaaS you host yourself. Compare the rupiah cost, the DSAL licence and who is paged. - [Claude Code on Bedrock, Google Cloud and Microsoft Foundry](https://www.matthewswong.com/en/blog/claude-code-bedrock-vertex-foundry-setup): Running Claude Code on a cloud provider keeps the CLI intact but drops a specific list of features. Here is what you lose, and how to set it up. - [Claude Code on the Web: Cloud Sessions and Teleport](https://www.matthewswong.com/en/blog/claude-code-on-the-web-cloud-sessions): A cloud session clones your GitHub remote, not your working copy — so push first. Here is the handoff in both directions and what only goes one way. - [Claude Code Behind an LLM Gateway: What Breaks and Why](https://www.matthewswong.com/en/blog/claude-code-llm-gateway-enterprise): A gateway centralises credentials and cost control, and quietly disables Remote Control, tool search and 1M verification. Here is the full list. - [SumoPod Review: Cheap Indonesian VPS for Self-Hosting](https://www.matthewswong.com/en/blog/sumopod-cheap-indonesian-vps-review): My hands-on SumoPod review: a cheap Indonesian VPS on Tencent Jakarta with real rupiah pricing, what I self-host on it, first-hour setup, and the catches. - [Biznet Gio vs IDCloudHost: Indonesia Cloud VPS Compared](https://www.matthewswong.com/en/blog/biznet-gio-vs-idcloudhost-indonesia-cloud): Compare Biznet Gio vs IDCloudHost on Jakarta data centers, rupiah pricing, performance, and support, and learn when a local cloud beats DigitalOcean. - [Sewa VPS Murah Indonesia: Panduan Jakarta Region 2026](https://www.matthewswong.com/en/blog/sewa-vps-murah-indonesia-panduan): How to choose a cheap Indonesian VPS (sewa VPS murah): Jakarta latency vs Singapore, IDR billing, local providers, workload sizing, and first-hour hardening. - [Cloudflare Workers vs Vercel Edge: Cold Starts, Pricing, Lock-In](https://www.matthewswong.com/en/blog/cloudflare-workers-vs-vercel-edge): Cloudflare Workers vs Vercel Functions in 2026: isolates vs Fluid compute, cold start behavior, pricing meters, egress costs, and where lock-in really lives. - [Azure Indonesia Central Region: A Developer's Complete Deployment Guide](https://www.matthewswong.com/en/blog/azure-indonesia-central-region-deployment-guide): Deploy to Azure Indonesia Central with Bicep, AKS availability zones, latency benchmarks vs Singapore, Azure OpenAI, and OJK data residency compliance. ## Blog — ERP Systems - [ERP AI Agent Tool Design: Drafts, Not Direct Writes](https://www.matthewswong.com/en/blog/erp-agent-tool-design-draft-documents): ERP AI agent tool design that protects the ledger: read, draft and post tiers, idempotency keys, branch scoping from tokens, errors written for a model. - [ERP Three-Way Match AI Agent: PO, Receipt and Invoice](https://www.matthewswong.com/en/blog/erp-three-way-match-ai-agent): Build an ERP three-way match AI agent that reads invoice PDFs, checks PO and goods receipt in code, explains variances and drafts AP entries for approval. - [Spec-Driven Development for ERP Requirements With AI Agents](https://www.matthewswong.com/en/blog/spec-driven-development-erp-requirements): ERP requirements arrive as edge cases, not a spec. How I write testable acceptance criteria, a worked-example table and an ambiguity log for agents. - [AI-Assisted Legacy ERP Refactor With No Written Spec](https://www.matthewswong.com/en/blog/ai-assisted-legacy-erp-refactor): An AI-assisted legacy ERP refactor with no written spec: pin behaviour with characterisation tests, cut the seams, and keep the agent out of posting code. - [ERP Domain Rules as a Claude Code Plugin: Skills and Hooks](https://www.matthewswong.com/en/blog/claude-code-plugin-erp-domain-toolkit): How I packaged ERP domain rules as a Claude Code plugin: path-scoped skills for conventions, always-loaded rules for invariants, hooks for hard guards. - [Connect an ERP POS to a Bluetooth Printer With Flutter](https://www.matthewswong.com/en/blog/connect-erp-pos-bluetooth-printer-flutter): Wire an ERP-backed POS to a 58 mm Bluetooth printer in Flutter: offline outbox, idempotent reprints, a printer port abstraction and field rollout. - [Epson TM-T82 ESC/POS Printing From a Custom POS App](https://www.matthewswong.com/en/blog/epson-tm-t82-escpos-pos-printing): How to print receipts on an Epson TM-T82 from a custom POS: ESC/POS byte streams, transports, 48-column layout maths and code page handling. - [Epson TM-T82 Cash Drawer, Auto Cutter and Status Bytes](https://www.matthewswong.com/en/blog/epson-tm-t82-cash-drawer-cutter-status): ESC p drawer pulses, GS V cutting without slicing the total, and DLE EOT real-time status: the ESC/POS commands a point-of-sale really needs. - [Coretax DJP Integration: e-Faktur & NPWP Guide for Devs](https://www.matthewswong.com/en/blog/coretax-djp-tax-integration-indonesia-developer): How Coretax DJP changed e-Faktur, e-Bupot, and NPWP for Indonesian ERP developers: 16-digit tax IDs, auto NSFP, and the new XML import schema. - [Kasbon ERP: Employee Cash Advance and Payroll Deduction](https://www.matthewswong.com/en/blog/kasbon-employee-cash-advance-payroll-deduction): How I modeled kasbon (Indonesian employee cash advance) in a NestJS ERP: request approval, cash-session disbursement, and automatic payroll deduction. - [ERP POS Cash-Session Reconciliation Design Guide](https://www.matthewswong.com/en/blog/pos-cash-session-reconciliation-design): How to design POS cash-session reconciliation in an ERP: opening float, cash-in/out, expected-vs-counted variance, close permissions, and an audit trail. - [Stock Opname ERP: ABC Cycle Counts Without Warehouse Freeze](https://www.matthewswong.com/en/blog/erp-stock-opname-cycle-count-indonesia): How to design ERP stock opname with ABC cycle counting, snapshot vs live counts, variance approval routing, and correct adjustment postings. - [Landed Cost Calculation in ERP: True Import Cost in Indonesia](https://www.matthewswong.com/en/blog/erp-landed-cost-import-calculation-indonesia): Learn how to calculate landed cost in a custom ERP by apportioning freight, insurance, bea masuk import duty, and PPN across purchase lines in Indonesia. - [Quote-to-Cash ERP Workflow: Quotation to Invoice to Payment](https://www.matthewswong.com/en/blog/erp-quotation-to-cash-sales-workflow): Build a quote-to-cash pipeline in a custom ERP: quotation, sales order, delivery, invoicing, and payment matching, powered by a strict state machine. - [ERP Multi-Company Intercompany Transactions & Elimination](https://www.matthewswong.com/en/blog/erp-multi-company-intercompany-transactions): Building ERP intercompany invoicing and automatic elimination entries across multiple legal entities for accurate consolidated financial reporting. - [Consignment Inventory in ERP: Modeling Stock You Don't Own](https://www.matthewswong.com/en/blog/erp-consignment-inventory-workflow): Learn how to model consignment inventory in a custom ERP: ownership vs possession, consignor settlements, and revenue recognition ledger entries on sale. - [e-Faktur Integration for ERP: PPN 11% and NSFP in Indonesia](https://www.matthewswong.com/en/blog/erp-e-faktur-tax-integration-indonesia): Learn how to integrate e-Faktur into a custom ERP: NPWP validation, PPN 11 percent calculation, NSFP invoice numbering, and DJP-ready export files. - [Batch and Serial Tracking in ERP: Full Traceability](https://www.matthewswong.com/en/blog/erp-batch-serial-number-traceability): Learn how to implement batch and serial number traceability in a custom ERP, covering receiving, movements, FEFO picking, and recall reporting. - [ERP General Ledger: Designing a Double-Entry Core in PostgreSQL](https://www.matthewswong.com/en/blog/erp-general-ledger-double-entry-design): Design a double-entry general ledger for an ERP system in PostgreSQL: chart of accounts, balanced journal entries, period close, and trial balance queries. - [ERP Manufacturing: BOM and MRP Module Design Guide](https://www.matthewswong.com/en/blog/erp-manufacturing-bom-mrp-design): Model multi-level bills of materials and MRP in a custom ERP: work orders, requirement runs, lead-time offsets, and backflushing stock on completion. - [ERP Fixed Asset Module: Depreciation Schedules Done Right](https://www.matthewswong.com/en/blog/erp-fixed-asset-depreciation-module): Design a fixed asset module for a custom ERP: asset registers, straight-line and declining-balance depreciation, disposal, and monthly GL posting. - [Procurement in ERP: PR to PO to Receipt to 3-Way Match](https://www.matthewswong.com/en/blog/erp-procurement-purchase-order-workflow): End-to-end ERP procurement workflow design: purchase requisitions, immutable POs, goods receipt screens for the dock, and a line-level 3-way match engine with tolerances. - [Outgrown Spreadsheets? A Decision Framework for SMBs](https://www.matthewswong.com/en/blog/spreadsheet-to-erp-decision-framework): Six concrete signals an SMB has outgrown spreadsheets, a one-hour scorecard to decide between Excel and ERP, and honest cases where staying on spreadsheets wins. - [ERP Adoption Playbook: Champions, Sandboxes, Cutover Comms](https://www.matthewswong.com/en/blog/erp-user-training-adoption-playbook): An operational ERP adoption playbook: champion networks with real responsibilities, sandbox programs on anonymized data, cutover communication calendars, and behavior metrics. - [ERP Reporting Architecture: Read Models That Save Your OLTP](https://www.matthewswong.com/en/blog/erp-reporting-dashboard-architecture): ERP reporting dashboard architecture explained: why analytics queries kill OLTP databases, and how materialized views, read models, and freshness budgets fix it. - [ERP Approval Matrix Design: Stop Hardcoding Approval Chains](https://www.matthewswong.com/en/blog/erp-approval-matrix-configuration): Design a configurable ERP approval matrix with amount bands, roles, and departments: schema, rule resolution, snapshot-at-submission, and the edge cases that hit production. - [Multi-Currency Accounting in ERP: Rates, FX Gains, IDR Rounding](https://www.matthewswong.com/en/blog/erp-multi-currency-accounting): How to design multi-currency accounting in a custom ERP: dual-currency journal lines, JISDOR rate pipelines, realized vs unrealized FX gains, and IDR rounding policy. - [ERP Inventory Module Design: Movements, Valuation, Guards](https://www.matthewswong.com/en/blog/erp-inventory-management-module-design): A practitioner's guide to ERP inventory module design: immutable stock movement ledgers, FIFO vs average cost valuation, and concurrency-safe negative stock guards in PostgreSQL. - [Odoo Custom Module Development for Indonesian Business](https://www.matthewswong.com/en/blog/odoo-erp-custom-module-development-indonesia): Learn to build Odoo custom modules for Indonesian PT companies — NPWP validation, multi-level purchase approval, ORM inheritance, and XML views in Odoo 17. - [ERP Data Migration: Avoid Costly Mistakes](https://www.matthewswong.com/en/blog/erp-data-migration-strategy): ERP data migration best practices: data cleansing, legacy field mapping, mock cutovers, rollback planning, and pitfalls that sink projects. - [Building an HR Leave Approval Flow in a Custom ERP](https://www.matthewswong.com/en/blog/erp-hr-leave-approval-flow): How I designed and built a transactional leave approval system from scratch using NestJS, PostgreSQL, and TypeORM—without Odoo or any off-the-shelf HR platform. - [Accounts Payable Multi-Level Approval Workflow in NestJS](https://www.matthewswong.com/en/blog/accounts-payable-multi-approval-nestjs): How I built a configurable, amount-based multi-level AP approval system with NestJS and PostgreSQL—from schema design to the approval chain algorithm. - [ERP Invoice PDF Generation: Puppeteer + Handlebars in NestJS](https://www.matthewswong.com/en/blog/erp-invoice-pdf-generation): A complete walkthrough of building invoice PDF export in a custom ERP system using Puppeteer, Handlebars templates, and NestJS—with Indonesian Rupiah formatting and PPN tax calculation. - [ERP Email Automation: Triggering Transactional Emails from Business Events](https://www.matthewswong.com/en/blog/erp-email-automation): How I built a reliable, queue-backed email automation layer for our custom ERP using NestJS EventEmitter2, BullMQ, and Nodemailer—with Handlebars templates and retry logic. - [Why ERP Implementations Fail in Indonesian Businesses — And How to Avoid It](https://www.matthewswong.com/en/blog/why-erp-fails-indonesian-businesses): An honest look at the most common ERP failure patterns in Indonesian SMEs — poor change management, under-resourcing, and customization creep — with practical advice to prevent them. - [Automating Accounts Receivable in a Custom ERP: Reminders, Aging Reports, and Payment Tracking](https://www.matthewswong.com/en/blog/accounts-receivable-automation-erp): How to build a fully automated AR system with NestJS and PostgreSQL — from invoice generation and scheduled reminder emails to aging reports and overdue escalation workflows. - [Building a Workflow Engine for Multi-Step Approvals: NestJS, PostgreSQL, and React](https://www.matthewswong.com/en/blog/workflow-engine-react-nestjs-postgresql): A deep dive into building a reusable state-machine workflow engine that powers leave requests, AP vouchers, and AR invoices in a custom ERP — with NestJS backend, JSONB history in PostgreSQL, and a React status UI. - [Migrating from Excel to a Custom ERP: Data Mapping, Validation, and Cutover Strategy](https://www.matthewswong.com/en/blog/excel-to-custom-erp-migration): A practical guide to migrating years of business data from Excel spreadsheets into a custom ERP — covering data mapping, Zod validation, bulk import scripts in NestJS, and a safe cutover strategy for Indonesian SMEs. - [Role-Based Access Control in a Custom ERP: NestJS Guards, PostgreSQL Permission Tables, and UU PDP Compliance](https://www.matthewswong.com/en/blog/erp-role-based-access-control): How to design and implement a production-grade RBAC system for a custom ERP — covering the PostgreSQL permission schema, NestJS custom guards, Redis-cached permission lookups, and compliance considerations under Indonesia's UU PDP. - [Building an ERP Audit Trail and Activity Log: PostgreSQL, NestJS Interceptors, and React Activity Feed](https://www.matthewswong.com/en/blog/erp-audit-trail-activity-log): How to implement a comprehensive audit logging system for a custom ERP — covering PostgreSQL schema design, NestJS interceptor-based logging, JSONB snapshots of before/after state, and a React activity feed component. - [Building a Multi-Level Purchase Order Approval Workflow in a Custom ERP](https://www.matthewswong.com/en/blog/erp-purchase-order-approval): How to design and implement a configurable purchase order approval system with NestJS and PostgreSQL — covering routing rules, delegation, escalation, and audit trails. - [Real-Time Inventory Tracking in a Custom ERP: From Stock Movements to Live Dashboards](https://www.matthewswong.com/en/blog/erp-inventory-real-time-tracking): A practical guide to building real-time inventory visibility in a custom ERP — stock movement events, warehouse locations, reorder automation, and live dashboards. - [Automating Financial Reporting in a Custom ERP: From Trial Balance to Management Reports](https://www.matthewswong.com/en/blog/erp-financial-reporting-automation): How to build automated financial reports — P&L, balance sheet, cash flow, and management dashboards — in a custom ERP using PostgreSQL and NestJS. - [Implementing Multi-Currency Support in a Custom ERP: Exchange Rates, Revaluation, and Reporting](https://www.matthewswong.com/en/blog/erp-multi-currency-implementation): A technical deep-dive into building multi-currency capability in a custom ERP — from exchange rate storage and transaction handling to unrealized gain/loss revaluation and consolidated reporting. - [Building a Vendor and Supplier Portal Integrated with Your Custom ERP](https://www.matthewswong.com/en/blog/erp-vendor-supplier-portal): How to design and build a self-service vendor portal that lets suppliers submit invoices, track payments, update documents, and collaborate directly with your ERP procurement module. - [Project Costing and Time Tracking in a Custom ERP: Budgets, Timesheets, and Profitability](https://www.matthewswong.com/en/blog/erp-project-costing-time-tracking): How to build a project costing module with time tracking, cost allocation, budget monitoring, and profitability reporting in a custom ERP using NestJS and PostgreSQL. - [Integrating Payroll with Your Custom ERP: From Timesheets to Payslips and Tax Reporting](https://www.matthewswong.com/en/blog/erp-payroll-integration-hr): A practical guide to building payroll integration in a custom ERP — connecting HR data, attendance, and timesheets to automated payslip generation and Indonesian tax reporting. - [Building a B2B Customer Portal Integrated with Your Custom ERP](https://www.matthewswong.com/en/blog/erp-customer-portal-b2b): How to design and build a customer-facing B2B portal that lets clients place orders, track shipments, view invoices, and pay online — fully integrated with your ERP's order and AR modules. - [Integrating Third-Party APIs with a Custom ERP: Patterns, Webhooks, and Error Handling](https://www.matthewswong.com/en/blog/erp-third-party-api-integration): A practical guide to connecting your custom ERP with external systems — payment gateways, logistics APIs, e-invoicing platforms, and government APIs — using NestJS middleware patterns. - [Building an Executive KPI Dashboard for Your Custom ERP](https://www.matthewswong.com/en/blog/erp-kpi-dashboard-executives): How to design and build a real-time executive KPI dashboard in a custom ERP — choosing the right metrics, data architecture, visualization, and performance optimization. - [Document Management in a Custom ERP: From File Uploads to Searchable Archives](https://www.matthewswong.com/en/blog/erp-document-management): How to build a document management system integrated with your ERP — file versioning, folder hierarchy, OCR search, workflow attachments, and compliance-ready archiving. - [Warehouse Barcode Scanning Integration in a Custom ERP: From Hardware to Real-Time Inventory](https://www.matthewswong.com/en/blog/erp-warehouse-barcode-scanning): How to integrate barcode scanning hardware with a custom ERP for real-time goods receipt, picking, and inventory adjustment — with a mobile-first React PWA and NestJS backend. - [Indonesian Tax Compliance in a Custom ERP: PPN, PPh, and e-Faktur Integration](https://www.matthewswong.com/en/blog/erp-tax-compliance-indonesia-ppn): A complete guide to implementing Indonesian tax compliance in a custom ERP — PPN (VAT) at 11%, PPh withholding, e-Faktur integration, and SPT reporting automation. - [Budget vs. Actual Variance Analysis in a Custom ERP: Real-Time Financial Control](https://www.matthewswong.com/en/blog/erp-budget-variance-analysis): How to build a budget variance analysis module in a custom ERP — from budget entry and actual posting to automated variance reports, exception alerts, and drill-down analysis. - [ERP and CRM Integration: Connecting Your Sales Pipeline to Operations](https://www.matthewswong.com/en/blog/erp-crm-integration-sales): How to integrate your custom ERP with a CRM system — syncing customers, quotes, orders, and inventory availability so your sales team has real-time business intelligence at their fingertips. - [Odoo vs SAP vs Custom ERP: Which Is Right for Your Business?](https://www.matthewswong.com/en/blog/odoo-vs-sap-vs-custom-erp): An honest comparison of Odoo, SAP Business One, and custom-built ERP systems — covering real costs, implementation timelines, and the situations where each option wins. - [ERP Implementation Timeline: The Reality vs. The Sales Pitch](https://www.matthewswong.com/en/blog/erp-implementation-timeline-reality): Why ERP projects almost always take longer than vendors promise, what phases actually consume the most time, and how to build a realistic timeline for an Indonesian SME implementation. - [ERP Change Management: Why People, Not Software, Determine Success](https://www.matthewswong.com/en/blog/erp-change-management-employees): The human side of ERP implementation — how to handle employee resistance, build internal champions, and run a change management program that actually drives adoption. - [ERP Data Quality and Migration Prep: The Work Nobody Wants to Do](https://www.matthewswong.com/en/blog/erp-data-quality-migration-prep): Why data migration is the most underestimated phase of any ERP project, how to audit and clean legacy data from Excel and Access, and a practical migration checklist for Indonesian SMEs. - [ERP ROI: Real Numbers from Real Implementations](https://www.matthewswong.com/en/blog/erp-roi-real-numbers): What ERP systems actually return on investment — with real calculations, honest timelines, and the metrics that matter for Indonesian SMEs making the business case. - [ERP Customization: A Brutal Cost-Benefit Analysis](https://www.matthewswong.com/en/blog/erp-customization-cost-benefit-analysis): When ERP customization is worth the cost and when it becomes technical debt — with real examples from Indonesian SME implementations and a framework for making the call. - [ERP Go-Live Checklist: 40 Items Before You Switch On](https://www.matthewswong.com/en/blog/erp-go-live-checklist): A comprehensive go-live checklist built from real ERP deployments — covering technical readiness, data validation, user readiness, rollback planning, and the first 48 hours. - [ERP User Training Strategy for Faster Adoption](https://www.matthewswong.com/en/blog/erp-user-training-strategy): How to design role-specific ERP training that actually drives adoption — with a practical training program structure, content templates, and the metrics that prove it's working. - [ERP Post Go-Live: What Happens in the First 90 Days](https://www.matthewswong.com/en/blog/erp-post-go-live-90-days): The first 90 days after ERP go-live are when implementations either stabilize or fail — what to monitor, how to support users, and the metrics that signal success or distress. - [ERP Process Mapping: The Requirements Work That Saves Your Project](https://www.matthewswong.com/en/blog/erp-process-mapping-guide): How to map business processes before ERP implementation — with practical swimlane diagram techniques, common mistakes to avoid, and a real example from an Indonesian SME. - [ERP Security and Permissions Design: RBAC Done Right](https://www.matthewswong.com/en/blog/erp-security-permissions-design): How to design a robust role-based access control system for your ERP — covering principle of least privilege, separation of duties, and the common security mistakes that create compliance risk. - [ERP Mobile and PWA for Field Workers: Offline-First Design](https://www.matthewswong.com/en/blog/erp-mobile-pwa-field-workers): How to extend your custom ERP to field workers using Progressive Web Apps — covering offline data sync, service workers, and the real-world constraints of mobile ERP in Indonesia. - [Migrating from Legacy Access Database to Custom ERP](https://www.matthewswong.com/en/blog/erp-legacy-access-db-migration): A practitioner's guide to replacing Microsoft Access with a modern ERP — the technical migration process, the data challenges, and how to manage the human side of moving away from a system people know. - [Cloud ERP vs On-Premise in Indonesia: Making the Right Call](https://www.matthewswong.com/en/blog/erp-cloud-vs-on-premise-indonesia): A frank comparison of cloud and on-premise ERP deployment for Indonesian SMEs — covering real cost differences, regulatory considerations, internet reliability, and the hybrid middle ground. - [ERP Middleware and Integration Design: Connecting Your Systems](https://www.matthewswong.com/en/blog/erp-middleware-integration-design): How to design a robust middleware integration layer for your custom ERP — covering API patterns, event-driven architecture, queue-based async processing, and the integration mistakes that cause data corruption. - [ERP Customization vs Configuration Explained](https://www.matthewswong.com/en/blog/erp-customization-vs-configuration): Configure or customize your ERP? Understand the risks, when customization is justified, and how to stay upgrade-safe while meeting business needs. - [ERP Integration: Connecting SAP & Oracle with APIs](https://www.matthewswong.com/en/blog/erp-integration-api-strategy): Strategy for integrating ERP systems (SAP, Oracle) with modern applications using REST APIs, middleware, iPaaS platforms, and event-driven architectures. - [ERP as the Backbone of Digital Transformation](https://www.matthewswong.com/en/blog/erp-digital-transformation): How ERP drives digital transformation: real-time visibility, process automation, cloud vs on-premise trade-offs, and building an integration-ready architecture. - [ERP Implementation Guide: Selection to Go-Live](https://www.matthewswong.com/en/blog/erp-implementation-guide): A practitioner's ERP implementation guide: requirements gathering, vendor selection, data migration, user training, go-live cutover, and post-go-live support. ## Blog — Backend & APIs - [A2A Protocol Tutorial: v1.0 Agent Cards, Tasks and Bindings](https://www.matthewswong.com/en/blog/a2a-protocol-v1-agent-cards-guide): A2A protocol tutorial for v1.0: publish a signed Agent Card, run the task lifecycle, stream or push updates, and choose JSON-RPC, gRPC or REST bindings. - [Durable AI Agents With Temporal: Survive Crashes and Waits](https://www.matthewswong.com/en/blog/durable-ai-agents-temporal-workflows): Build durable AI agents with Temporal: the workflow and activity split, OpenAI Agents SDK and Pydantic AI code, and an ERP approval that survives deploys. - [MCP 2026-07-28 Spec Migration: Stateless Guide for Servers](https://www.matthewswong.com/en/blog/mcp-2026-07-28-stateless-spec-migration): MCP 2026-07-28 spec migration for servers: replace Mcp-Session-Id, return input_required instead of elicitation, add Mcp-Method headers, drop LB affinity. - [OpenAI Assistants API Shutdown Migration to the Responses API](https://www.matthewswong.com/en/blog/openai-assistants-api-shutdown-migration): Assistants API shutdown migration playbook: move assistants into code, threads to Conversations, runs to Responses, and rebuild thread history yourself. - [PaaS Postgres Connection Limits: Surviving max_connections](https://www.matthewswong.com/en/blog/paas-postgres-connection-limits-survival): On a PaaS every new replica opens its own Postgres pool. Here is the max_connections arithmetic that predicts the outage, and how to size a pool down. - [Reviewing AI-Written Postgres Migrations Before They Run](https://www.matthewswong.com/en/blog/ai-database-migration-safety-review): AI-written Postgres migrations are valid SQL that can still lock a live table. The lock each statement takes, five real failures, and the review checklist. - [Durable Execution for AI Agents: Surviving Hours-Long Runs](https://www.matthewswong.com/en/blog/durable-execution-ai-agent-workflows): Durable execution for AI agents replays a journal, so a crash resumes at the failed step instead of re-paying for every LLM call the run already made. - [My ERP Approval npm Library Passed 1,200 Weekly Downloads](https://www.matthewswong.com/en/blog/hierarchical-approval-1200-weekly-downloads): My open-source ERP approval workflow npm library passed 1,204 weekly downloads in eleven weeks. Parallel branch groups, five modes, 404 tests, v4.0.0. - [Deploy a NestJS ERP API to a Managed PaaS: Probes, Migrations](https://www.matthewswong.com/en/blog/deploy-nestjs-erp-api-paas-guide): Deploying a NestJS ERP API to a managed PaaS: shutdown hooks, health probes that will not restart a healthy pod, and migrations that run exactly once. - [Epson TM-T82 Network Printing: Port 9100 Troubleshooting](https://www.matthewswong.com/en/blog/epson-tm-t82-network-printing-troubleshooting): Network receipt printer stopped printing? Diagnose port 9100 sessions, half-open sockets and DHCP moves, then queue every receipt idempotently. - [AI Agents for ERP Development: Real Use Cases](https://www.matthewswong.com/en/blog/ai-agents-erp-development-use-cases): AI agents for ERP development, from scaffolding modules to MCP integrations and approval workflows, plus where human judgment must stay firmly in charge. - [MCP Primitives: Tools, Resources, and Prompts](https://www.matthewswong.com/en/blog/mcp-tools-resources-prompts-primitives): MCP tools, resources, and prompts explained: the three server primitives, how they differ in code, and a simple rule for choosing the right one. - [MCP Transports: stdio vs Streamable HTTP](https://www.matthewswong.com/en/blog/mcp-transports-stdio-vs-http): MCP transports stdio vs HTTP: how a local subprocess server differs from a remote Streamable HTTP service, and when to use each in your setup. - [Build an MCP Server in TypeScript: A Guide](https://www.matthewswong.com/en/blog/build-mcp-server-typescript-guide): Build an MCP server in TypeScript with the official SDK: scaffold it, add a typed tool, connect it to Claude, and take it from local to production. - [Distributed Locking with Redis Redlock in Node.js](https://www.matthewswong.com/en/blog/distributed-locking-redis-redlock-nodejs): How I use Redis Redlock for distributed locking in Node.js: the quorum algorithm, TTL auto-extension, node-redlock, fencing tokens, and Postgres alternatives. - [Turso and libSQL: Edge SQLite with Embedded Replicas](https://www.matthewswong.com/en/blog/turso-libsql-edge-sqlite): How Turso and libSQL turn SQLite into an edge database: embedded replicas for local reads, remote writes that sync, and database-per-tenant at scale. - [DuckDB: In-Process OLAP Analytics on Parquet, CSV, and S3](https://www.matthewswong.com/en/blog/duckdb-in-process-analytics): DuckDB is an in-process OLAP database that runs SQL directly on Parquet, CSV, and S3 files with zero ETL. See how it compares to Postgres and a warehouse. - [Run TypeScript Natively in Node.js: Type Stripping](https://www.matthewswong.com/en/blog/nodejs-native-typescript-type-stripping): Run TypeScript directly in Node.js with type stripping, no tsc build step. How experimental-strip-types works, its limits, and when to use transform mode. - [PostgreSQL 18: Async I/O, uuidv7 and Skip Scan Explained](https://www.matthewswong.com/en/blog/postgresql-18-async-io-performance): PostgreSQL 18 ships asynchronous I/O with io_uring, native uuidv7(), virtual generated columns by default, B-tree skip scan, and OAuth authentication. - [HTTP QUERY Method: The Safe GET With a Body (RFC 10008)](https://www.matthewswong.com/en/blog/http-query-method-rfc-10008): The HTTP QUERY method (RFC 10008) is a safe, idempotent, cacheable request with a body. Learn how it beats GET-with-body and POST for search APIs. - [Midtrans Snap Payment Gateway Integration in Next.js](https://www.matthewswong.com/en/blog/midtrans-payment-gateway-integration-nextjs): Integrate Midtrans Snap into Next.js: create a transaction token server-side, launch the Snap popup, and verify the webhook SHA512 signature key safely. - [Dynamic QRIS Payment Integration in Node.js (MPM, Midtrans)](https://www.matthewswong.com/en/blog/qris-dynamic-payment-integration-nodejs): Integrate dynamic QRIS payments in Node.js: static vs dynamic QRIS, the MPM flow, generating a QR via a licensed PSP, webhooks, NMID, and MDR fees. - [WhatsApp Business API Integration for Indonesia (Cloud API)](https://www.matthewswong.com/en/blog/whatsapp-business-api-integration-indonesia): Integrate the official WhatsApp Business Cloud API for Indonesian notifications: message templates, webhooks, the 24-hour window, and per-message pricing. - [Bun vs Node.js Production Runtime in 2026: Which to Use](https://www.matthewswong.com/en/blog/bun-vs-nodejs-production-runtime): Bun vs Node.js as a production runtime in 2026 — startup speed, install times, built-in tooling, and native addon compatibility gaps compared, with a decision table. - [Drizzle ORM vs Prisma: TypeScript Backend ORM Guide](https://www.matthewswong.com/en/blog/drizzle-orm-vs-prisma-typescript): Drizzle ORM vs Prisma for TypeScript backends: compare SQL-first vs schema-first, bundle size, edge runtime support, and migration workflows. - [Hono Edge API Framework: Workers, Bun, Node Guide](https://www.matthewswong.com/en/blog/hono-edge-api-framework-guide): A practical guide to Hono, the Web-Standards edge API framework: routing, middleware, running one app on Cloudflare Workers, Bun, and Node, and typed RPC. - [NATS JetStream vs Kafka: Streams for Lean Teams](https://www.matthewswong.com/en/blog/nats-jetstream-vs-kafka-lightweight): NATS JetStream vs Kafka for teams that do not need Kafka's scale. Compare streams, consumers, delivery guarantees, and operational simplicity, with a table. - [NestJS Request-Scoped Providers: DI Gotchas & Fixes](https://www.matthewswong.com/en/blog/nestjs-request-scoped-providers-di-gotchas): How NestJS request-scoped providers work, why scope bubbling and per-request cost bite in production, and when AsyncLocalStorage is the safer request-context fix. - [openapi-typescript: End-to-End Type Safety for APIs](https://www.matthewswong.com/en/blog/openapi-typescript-end-to-end-types): Generate TypeScript types from an OpenAPI spec with openapi-typescript and openapi-fetch for a typed client that catches frontend and backend drift at compile time. - [OpenTelemetry Tracing in NestJS with Auto-Instrumentation](https://www.matthewswong.com/en/blog/opentelemetry-tracing-nestjs-auto-instrumentation): Add distributed tracing to a NestJS API with OpenTelemetry auto-instrumentation: NodeSDK setup, W3C context propagation, and exporting spans to a collector. - [PostgreSQL Zero-Downtime Upgrade with Logical Replication](https://www.matthewswong.com/en/blog/postgres-logical-replication-zero-downtime-upgrade): How to upgrade PostgreSQL across major versions with near-zero downtime using logical replication, plus the sequence and large-object gotchas at cutover. - [Server-Sent Events vs WebSockets for Realtime Apps](https://www.matthewswong.com/en/blog/server-sent-events-vs-websockets-realtime): A practical comparison of Server-Sent Events vs WebSockets: one-way vs bidirectional, reconnection, proxy and HTTP/2 behaviour, and how to choose. - [Postgres UNION View for a Derived ERP Cash Book Ledger](https://www.matthewswong.com/en/blog/derived-cash-book-union-view-postgres): How I built an ERP cash book as a derived Postgres UNION view over payments, expenses, and kasbon instead of a drift-prone denormalized table. - [Integer Money in IDR: Why ERP Backends Avoid Float](https://www.matthewswong.com/en/blog/integer-money-idr-avoid-float-errors): Why the JID Carwash ERP backend stores money as integer rupiah, never float — Prisma Int vs BigInt vs Decimal, rounding bugs, and safe display formatting. - [POS Payment Idempotency Keys in NestJS + Prisma](https://www.matthewswong.com/en/blog/pos-payment-settlement-idempotency-keys): How idempotency keys, a Postgres unique constraint, and a settlement spec test stop a POS from double-charging on a double-tap or network retry in NestJS. - [Inventory Source of Truth: Append-Only Stock Movement Ledger](https://www.matthewswong.com/en/blog/stock-movement-source-of-truth-vs-cached-qty): Why SUM of an append-only StockMovement ledger is the real inventory source of truth and Product.stockQty is only a cache you rebuild and reconcile. - [Shopee & Tokopedia Seller API Integration Guide](https://www.matthewswong.com/en/blog/tokopedia-shopee-marketplace-api-integration): A backend engineer's guide to Shopee Open Platform and Tokopedia (TikTok Shop) seller APIs: OAuth, order and stock sync, product upload, and omnichannel middleware. - [Xendit vs Midtrans: Indonesia Payment Gateway Compared](https://www.matthewswong.com/en/blog/xendit-vs-midtrans-payment-gateway-indonesia): Compare Xendit vs Midtrans for Indonesian payments: Virtual Account, QRIS, e-wallet, card fees, developer experience, and disbursement — which to pick. - [Expand/Contract Pattern for Zero-Downtime Schema Migration](https://www.matthewswong.com/en/blog/expand-contract-schema-migration-pattern): Learn the expand/contract (parallel change) pattern for zero-downtime schema migrations: add, backfill, dual-write, switch, and drop columns safely on a live Postgres database. - [Idempotent Consumer Pattern for Message Queues](https://www.matthewswong.com/en/blog/idempotent-consumer-pattern-message-queue): Build exactly-once effects on at-least-once delivery using the idempotent consumer pattern: a processed-messages table, unique constraints, and one transaction. - [PgBouncer Pooling Modes: Session vs Transaction Explained](https://www.matthewswong.com/en/blog/pgbouncer-connection-pooling-modes): PgBouncer pooling modes compared: session vs transaction vs statement, the prepared-statement pitfall in transaction mode, and how to size pool_size correctly. - [PostgreSQL EXPLAIN ANALYZE: Reading Query Plans](https://www.matthewswong.com/en/blog/postgres-explain-analyze-reading-query-plans): Learn to read PostgreSQL EXPLAIN ANALYZE output: seq scan vs index scan, nested loop vs hash join, buffers, and how to spot the real query bottleneck. - [PostgreSQL Generated Columns: STORED, Indexing & Derived Data](https://www.matthewswong.com/en/blog/postgres-generated-columns-computed-data): How PostgreSQL generated columns work: STORED vs VIRTUAL, indexing computed columns, immutability rules, and moving derived logic into the database safely. - [SQLite Litestream Replication in Production Guide](https://www.matthewswong.com/en/blog/sqlite-litestream-replication-production): How Litestream streams SQLite changes to object storage for continuous backup and point-in-time restore, plus where single-node SQLite actually shines. - [Valkey vs Redis: Fork Migration Guide for Backend Teams](https://www.matthewswong.com/en/blog/valkey-vs-redis-fork-migration): Valkey vs Redis after the license fork: what changed, real drop-in compatibility, a full comparison table, and whether your backend should migrate in 2026. - [Saga Pattern in NestJS: Distributed Transactions Without 2PC](https://www.matthewswong.com/en/blog/saga-pattern-distributed-transactions-nestjs): Learn the saga pattern in NestJS for distributed transactions: orchestration vs choreography, compensating actions, and idempotent step design explained. - [Postgres Job Queue with SELECT FOR UPDATE SKIP LOCKED](https://www.matthewswong.com/en/blog/postgres-skip-locked-job-queue): Build a reliable PostgreSQL job queue with SELECT FOR UPDATE SKIP LOCKED: safe concurrent workers, no double-processing, and when to switch to a real broker. - [Transactional Outbox Pattern in PostgreSQL: Reliable Events](https://www.matthewswong.com/en/blog/transactional-outbox-pattern-postgres): The transactional outbox pattern in PostgreSQL prevents dual-write bugs by reliably publishing domain events via an outbox table and relay poller. - [Reliable Webhooks: HMAC Signing, Retries, Idempotency, Replay](https://www.matthewswong.com/en/blog/webhooks-reliable-delivery-design): Learn to design reliable webhooks with HMAC signing, exponential backoff retries, idempotency keys, and a replayable event log for trustworthy delivery. - [Feature Flags in NestJS: Progressive Rollouts and Kill Switches](https://www.matthewswong.com/en/blog/feature-flags-nestjs-progressive-rollout): Add feature flags to a NestJS backend: percentage rollouts, per-tenant targeting, and kill switches that stop a bad release without a redeploy. - [Testing NestJS Applications: Unit, Integration, E2E Guide](https://www.matthewswong.com/en/blog/testing-nestjs-applications-guide): A practical guide to testing NestJS applications: unit tests with mocked providers, integration tests with a real database, and e2e tests via supertest. - [Zero-Downtime Database Migrations with Prisma and Postgres](https://www.matthewswong.com/en/blog/zero-downtime-database-migrations-prisma): Learn zero-downtime database migrations with Prisma using the expand-contract pattern: backfills, dual-write windows, and safely dropping old columns. - [PostgreSQL Row-Level Security for Multi-Tenant SaaS](https://www.matthewswong.com/en/blog/postgres-row-level-security-multitenant): Enforce tenant isolation in PostgreSQL with row-level security policies, session variables, and connection-pooling-safe SET LOCAL testing patterns. - [NestJS Custom Decorators: Metadata, Reflector & Guards](https://www.matthewswong.com/en/blog/nestjs-custom-decorators-metadata-reflection): Learn NestJS custom decorators, SetMetadata, and Reflector to read metadata at request time — build @CurrentUser and @Roles guards the right way. - [I Built an npm Library for ERP Hierarchical Approval Workflows](https://www.matthewswong.com/en/blog/hierarchical-approval-npm-library): Open-source TypeScript npm library for ERP hierarchical approval workflows. Templates, optimistic locking, idempotency, and test-friendly time injection. - [NestJS Health Checks with Terminus for Kubernetes & Docker](https://www.matthewswong.com/en/blog/nestjs-terminus-health-checks): Add liveness and readiness probes to NestJS with @nestjs/terminus, then wire them into Docker HEALTHCHECK and Kubernetes probes for zero-downtime deploys. - [Marketplace Price Monitoring SaaS: Tokopedia and Shopee](https://www.matthewswong.com/en/blog/marketplace-price-monitoring-saas-tokopedia-shopee): Build a marketplace price monitoring SaaS for Tokopedia and Shopee sellers: data acquisition options, monitoring pipeline, alerts, and honest ToS caution. - [Reliable Background Jobs with BullMQ and NestJS](https://www.matthewswong.com/en/blog/background-jobs-bullmq-nestjs): Production blueprint for background jobs in NestJS with BullMQ and Redis: retry and exponential backoff configuration, dead-letter queues, idempotent processors, and monitoring. - [Idempotency Keys: Designing APIs That Survive Retries](https://www.matthewswong.com/en/blog/idempotency-keys-api-design): How to design idempotent API endpoints with idempotency keys: atomic key claims in PostgreSQL, request hashing, replay semantics, Stripe's 24-hour model, and client rules. - [Multi-Tenant SaaS Architecture With Postgres RLS](https://www.matthewswong.com/en/blog/multi-tenant-saas-postgres-rls-indonesia): How to build a multi-tenant SaaS architecture with Postgres RLS: compare isolation models and enforce tenant_id in the database, not the app layer. - [PostgreSQL Indexing in Practice: B-tree, GIN, and Partial Indexes](https://www.matthewswong.com/en/blog/postgres-indexing-practical-guide): Practical PostgreSQL indexing guide: choosing between B-tree, GIN, GiST, and BRIN, designing partial and composite indexes, and reading EXPLAIN ANALYZE with real numbers. - [SaaS Recurring Billing in Indonesia: Midtrans and Xendit](https://www.matthewswong.com/en/blog/saas-recurring-billing-midtrans-xendit-qris-indonesia): A guide to SaaS recurring billing in Indonesia using Midtrans, Xendit, and QRIS: tokenization, the subscription state machine, dunning, and webhooks. - [WhatsApp Invoice Reminder SaaS: Build It for Indonesia](https://www.matthewswong.com/en/blog/whatsapp-invoice-reminder-saas-indonesia): Learn how to build a WhatsApp invoice reminder SaaS for Indonesian UKM using the Cloud API, message templates, a reminder scheduler, and payment tracking. - [Indonesia SNAP API & QRIS 2.0: Open Banking Developer Guide](https://www.matthewswong.com/en/blog/indonesia-open-banking-snap-api-qris-developer-guide): Implement Bank Indonesia's SNAP API with OAuth 2.0, HMAC-SHA512 signing, QRIS 2.0 cross-border payments, and production-ready Node.js examples for Indonesian fintech. ## Blog — Software Development - [Open Source Maintenance from Indonesia: The UTC+7 Timezone Tax](https://www.matthewswong.com/en/blog/indonesian-open-source-maintainer-sustainability): Maintaining an open source package from Indonesia at UTC+7 with a day job: the review-latency tax, batched triage, issue forms, scope and funding. - [AI Commit Messages and Changelog Automation: Why Beats What](https://www.matthewswong.com/en/blog/ai-commit-message-changelog-automation): Generating a commit message from a diff only restates what git show proves. Where the why actually lives, and the shell trap that eats backticks. - [AI-Generated Tests: Coverage Rose, Mutation Score Did Not](https://www.matthewswong.com/en/blog/ai-generated-tests-coverage-honesty): An AI agent writing tests asserts what the code already does, so coverage rises and nothing is verified. Mutation testing is what exposes the gap. - [Bundling LSP Servers in a Claude Code Plugin, and Its Cost](https://www.matthewswong.com/en/blog/claude-code-plugin-lsp-bundling-guide): A Claude Code plugin can declare language servers in an .lsp.json file, so installing the bundle configures them. What it cannot ship, and what it costs. - [Migrating Claude Code Dotfiles into a Versioned Plugin](https://www.matthewswong.com/en/blog/claude-code-dotfiles-to-plugin-migration): Migrating Claude Code dotfiles into a versioned plugin: the file-by-file map, the hook that fired twice, and the components you lose without noticing. - [Claude Code Plugin Marketplace Curation: What Earns a Slot](https://www.matthewswong.com/en/blog/claude-code-plugin-marketplace-curation): How I curate an internal Claude Code plugin marketplace: what earns a slot, the review bar for a third-party bundle, named owners, and safe retirement. - [Claude Code Plugin vs Skill: When to Bundle a Workflow](https://www.matthewswong.com/en/blog/claude-code-plugin-vs-skill-bundling): Claude Code plugin vs skill: a skill is a document, a plugin is a dependency. Bundle a workflow only when drift between copies is the real problem. - [Claude Code Plugin Eval: Catch a Skill That Never Activates](https://www.matthewswong.com/en/blog/claude-code-plugin-eval-test-suite): Claude Code plugin eval explained: writing eval cases and graders, reading the ablation delta, and catching a skill whose description never activates. - [Claude Code Interactive Mode: Shortcuts and Prompt Tricks](https://www.matthewswong.com/en/blog/claude-code-interactive-mode-shortcuts): The Claude Code prompt box does more than send text. Here are the sigils, the queue, side questions, and the shortcuts worth learning first. - [Claude Code LSP Plugins: Real Code Intelligence for Claude](https://www.matthewswong.com/en/blog/claude-code-lsp-code-intelligence): An LSP plugin gives Claude type errors after every edit and real code navigation. Here are the eleven languages, the costs, and custom servers. - [Claude Code Errors: What They Mean and How to Fix Them](https://www.matthewswong.com/en/blog/claude-code-troubleshooting-common-errors): Most Claude Code errors are configuration, not bugs. Here are the common ones by family, the two commands to run first, and the actual fixes. - [Claude Code CLI Flags: The Ones Worth Knowing by Job](https://www.matthewswong.com/en/blog/claude-code-cli-reference-flags-guide): The Claude Code CLI has dozens of flags and two dozen subcommands. Here are the ones that change outcomes, grouped by the job each one does. - [Claude Code Sessions: Resume, Branch and Name Your Work](https://www.matthewswong.com/en/blog/claude-code-sessions-resume-branch-naming): A session is a saved conversation on disk. Here is what resuming restores, what it quietly drops, and the difference between branch and fork. - [Claude Code Desktop Scheduled Tasks: Local Automation](https://www.matthewswong.com/en/blog/claude-code-desktop-scheduled-tasks): Desktop tasks run on your machine with your files, and catch up when it wakes. Write the prompt for the time it might actually run, not the time you set. - [Claude Code for JetBrains: The Plugin and Its MCP Server](https://www.matthewswong.com/en/blog/claude-code-jetbrains-plugin-guide): The JetBrains plugin runs a local MCP server, shares your editor selection on every prompt, and carries one security note that is specific to IDEs. - [Claude Code in VS Code: The Extension, Not the CLI](https://www.matthewswong.com/en/blog/claude-code-vs-code-extension-guide): The extension bundles its own CLI and still does not put claude on your PATH. Here is what it does better than the terminal, and what only the CLI has. - [Claude Code Accessibility: Screen Readers and Beyond](https://www.matthewswong.com/en/blog/claude-code-accessibility-screen-reader): Screen reader mode replaces the terminal interface with labelled linear text. Here is how to enable it, what it announces, and the settings for magnifiers. - [Claude Code Fullscreen: Flicker-Free, With Trade-Offs](https://www.matthewswong.com/en/blog/claude-code-fullscreen-focus-view-tui): Fullscreen rendering kills flicker and flattens memory by drawing on the alternate screen. That costs native scrollback and mouse selection. - [Claude Code Keybindings: Rebind, Unbind and Chords](https://www.matthewswong.com/en/blog/claude-code-keybindings-customization): Keybindings live in one hot-reloaded file, scoped by context. Here is the chord prefix rule that blocks a rebind, and the four keys you cannot touch. - [Claude Code Status Line: Context, Cost and Cache Live](https://www.matthewswong.com/en/blog/claude-code-statusline-customization): A status line is a shell script fed JSON on stdin. Here are the fields worth rendering, the width trap, and why a slow script silently shows nothing. - [Claude Code Terminal Setup: Shift+Enter, Bells, Themes](https://www.matthewswong.com/en/blog/claude-code-terminal-setup-notifications): Shift+Enter submitting, no alert when Claude finishes, a word vanishing on Backspace — all one-line fixes. Here is the symptom-to-setting index. - [Flutter Bluetooth Thermal Printer Setup: Panda 58mm POS](https://www.matthewswong.com/en/blog/flutter-panda-bluetooth-thermal-printer-setup): Connect a Flutter POS app to a Panda 58 mm Bluetooth thermal printer: transports, package choice, pairing order and the first working receipt. - [Build 58mm ESC/POS Receipts in Flutter With esc_pos_utils](https://www.matthewswong.com/en/blog/flutter-escpos-receipt-builder-58mm): A testable 58 mm receipt builder in Dart: the 32-column budget, the 12-unit PosColumn grid, rupiah widths, native QR codes and golden byte tests. - [Flutter Bluetooth Permissions on Android 12+ for Printers](https://www.matthewswong.com/en/blog/flutter-bluetooth-permissions-android-12-printer): BLUETOOTH_SCAN, BLUETOOTH_CONNECT and neverForLocation explained for Flutter POS apps, with the manifest and runtime request that survive Play review. - [Fixing Garbled Flutter Bluetooth Thermal Printer Receipts](https://www.matthewswong.com/en/blog/flutter-thermal-printer-garbled-receipt-fixes): Symptom-first debugging for Flutter thermal printing: code page mismatches, buffer overruns, chunked writes, wrong paper size and a five-minute triage. - [Epson TM-T82: Windows Driver vs Raw ESC/POS Printing](https://www.matthewswong.com/en/blog/epson-tm-t82-driver-vs-raw-escpos): Driver, OPOS, ePOS-Print or raw bytes for an Epson TM-T82? A practical comparison of speed, cash drawer control and failure modes, with code. - [AI Agents for Legacy Code Migration: A Guide](https://www.matthewswong.com/en/blog/ai-agents-legacy-code-migration): How to use AI agents for legacy code migration safely: build characterization tests first, migrate in verifiable slices, and fan out with headless batches. - [Verification Loops: The Core Agentic Coding Skill](https://www.matthewswong.com/en/blog/verification-loops-agentic-coding): The verification loop is the core agentic coding skill: give your AI agent a fast, deterministic check to grade its own work and iterate to green. - [How to Test AI-Generated Code: Best Practices](https://www.matthewswong.com/en/blog/testing-ai-generated-code-guide): Best practices for testing AI-generated code: layer unit, integration, and edge-case tests, add types and lint gates, and review the diff you cannot trust. - [Spec-First AI Coding: Let the Agent Interview You](https://www.matthewswong.com/en/blog/spec-first-agent-interview-workflow): Spec-first AI coding makes the agent interview you into a written spec before it writes code, so misunderstandings surface as cheap words, not costly code. - [Vibe Coding vs Spec-Driven Development](https://www.matthewswong.com/en/blog/vibe-coding-vs-spec-driven-development): Vibe coding vs spec-driven development compared: speed, risk, the seventy percent problem, and how to switch between loose and disciplined AI coding. - [TDD With AI Coding Agents: A Practical Workflow](https://www.matthewswong.com/en/blog/tdd-with-ai-coding-agents): A practical guide to TDD with AI coding agents: write failing tests first, freeze them, and let the agent iterate to green on error paths and edge cases. - [AGENTS.md vs CLAUDE.md: Agent Context Files](https://www.matthewswong.com/en/blog/agents-md-vs-claude-md): AGENTS.md vs CLAUDE.md compared: where each agent context file came from, which tools read it, what to put inside, and how to support both from one source. - [Integration Testing NestJS with Testcontainers and Postgres](https://www.matthewswong.com/en/blog/testcontainers-nestjs-integration-testing): How I integration-test NestJS against a throwaway Postgres with Testcontainers and Jest, catching SQL and constraint bugs that mocked repositories miss. - [TypeScript using Keyword: Explicit Resource Management](https://www.matthewswong.com/en/blog/typescript-using-keyword-disposal): How TypeScript's using and await using keywords auto-close DB connections, files, and locks at scope end with Symbol.dispose and Symbol.asyncDispose. - [pnpm Catalogs: Fix Monorepo Dependency Version Drift](https://www.matthewswong.com/en/blog/pnpm-catalogs-monorepo-versions): How I use pnpm Catalogs and workspaces to centralize monorepo dependency versions, end version drift and merge conflicts, plus where Turborepo fits. - [JavaScript Iterator Helpers (ES2025): Lazy map/filter/take](https://www.matthewswong.com/en/blog/javascript-iterator-helpers-es2025): JavaScript iterator helpers landed in ES2025: lazy map, filter, take, drop and flatMap on iterators. Learn the memory wins, runtime support and limits. - [Deno 2: Node.js and npm Compatibility for Existing Projects](https://www.matthewswong.com/en/blog/deno-2-nodejs-compatibility): How Deno 2 becomes a drop-in for Node projects with package.json, node_modules, npm and jsr specifiers, an all-in-one CLI, workspaces, and LTS. - [TypeScript Goes Native: The 10x Faster Go Compiler tsgo](https://www.matthewswong.com/en/blog/typescript-native-go-compiler-tsgo): Microsoft is rewriting TypeScript in Go for a 10x faster compiler. Inside tsgo, TypeScript 7, the VS Code benchmarks, and how to try the preview. - [Effect-TS: Typed Functional Error Handling in TypeScript](https://www.matthewswong.com/en/blog/effect-ts-functional-error-handling): How Effect-TS encodes typed errors, async, and dependency injection in one signature — taming TypeScript failure handling without hidden exceptions. - [Flutter Offline-First Outbox Sync for Field Apps](https://www.matthewswong.com/en/blog/flutter-offline-outbox-sync-field-app): How I built an offline-first outbox sync in a Flutter field app: connectivity_plus network watching, idempotent replay, and conflict handling to a NestJS API. - [Repository Adapter Pattern for Next.js + Flutter Offline Parity](https://www.matthewswong.com/en/blog/mock-real-repository-adapter-offline-parity): How the repository adapter pattern gave our Next.js POS and Flutter carwash app full offline and demo parity from one shared TypeScript types contract. - [TypeScript satisfies Operator: Config and Route Map Patterns](https://www.matthewswong.com/en/blog/typescript-satisfies-operator-patterns): Learn the TypeScript satisfies operator: validate a value against a type while keeping its narrow inferred type, with patterns for config objects and route maps. - [API Versioning Strategies: URL, Header, or No Version at All](https://www.matthewswong.com/en/blog/api-versioning-strategies-rest): REST API versioning strategies compared: URL paths, GitHub-style header versions, Stripe's date-pinned model, and additive-only evolution that avoids breaking clients. - [Event-Driven Architecture: When NOT to Use It](https://www.matthewswong.com/en/blog/event-driven-architecture-when-not-to): Honest decision criteria for event-driven architecture: the hidden costs of brokers, when synchronous calls and Postgres transactions win, and when events truly earn their place. - [Next.js Performance: Core Web Vitals & Beyond](https://www.matthewswong.com/en/blog/nextjs-performance-optimization): Optimize Next.js for Core Web Vitals: image optimization, font loading, code splitting, React Server Components, caching strategies, and bundle analysis. - [PostgreSQL Performance: Indexing & Query Tuning](https://www.matthewswong.com/en/blog/database-optimization-postgresql): Speed up PostgreSQL queries with B-tree indexes, partial indexes, EXPLAIN ANALYZE, query planning, connection pooling with PgBouncer, and VACUUM strategies. - [Software Architecture: MVC, CQRS, Event-Driven](https://www.matthewswong.com/en/blog/software-architecture-patterns): Compare MVC, CQRS, and Event-Driven Architecture. Learn when each pattern fits your use case, trade-offs, and how to combine them in modern applications. - [Test-Driven Development: Write Tests First](https://www.matthewswong.com/en/blog/test-driven-development-tdd): Master the Red-Green-Refactor cycle of TDD. Practical unit test examples with Jest and TypeScript, plus when TDD pays off and when it slows you down. - [REST vs GraphQL: Choosing the Right API Design](https://www.matthewswong.com/en/blog/api-design-rest-graphql): REST or GraphQL? Compare performance, flexibility, tooling, and when each wins. Real examples of REST endpoints vs GraphQL queries for the same data model. - [Microservices vs Monolith: When to Split](https://www.matthewswong.com/en/blog/microservices-vs-monolith): Should you break your monolith into microservices? Learn the real trade-offs, when each architecture wins, and migration strategies that don't break your team. - [Clean Code Principles Every Developer Should Know](https://www.matthewswong.com/en/blog/clean-code-principles): Master clean code with SOLID principles, meaningful naming, small functions, and refactoring techniques. Practical examples in TypeScript and JavaScript. ## Blog — Web Development - [Next.js Standalone Docker Image Size: A Real Dockerfile](https://www.matthewswong.com/en/blog/nextjs-standalone-docker-image-size): What Next.js output standalone traces into a Docker image, the two directories it never copies for you, and the multi-stage Dockerfile this site deploys. - [Claude Code Plugin for Next.js: Skill, Hook, Subagent](https://www.matthewswong.com/en/blog/claude-code-plugin-nextjs-stack-toolkit): The complete Claude Code plugin for a Next.js App Router codebase: manifest, a server and client boundary skill, a typecheck hook, and an SEO subagent. - [Claude Code Artifacts: Publish a Page From a Session](https://www.matthewswong.com/en/blog/claude-code-artifacts-publishing-guide): An artifact is a live page on claude.ai published from your session. Here are the CSP constraints, connector model, and where it silently will not work. - [Answer Engine Optimization (AEO): Get Cited by AI Search](https://www.matthewswong.com/en/blog/answer-engine-optimization-ai-search): How to make content quotable by ChatGPT, Perplexity, and Google AI Overviews with answer-first structure, FAQPage and TechArticle schema, and AEO metrics. - [Speculation Rules API: Instant Prerender and Prefetch in Chrome](https://www.matthewswong.com/en/blog/speculation-rules-api-prerendering): The Speculation Rules API prerenders and prefetches pages in Chromium for instant navigation. Learn the JSON syntax, eagerness levels, and the pitfalls. - [JavaScript Temporal API: The Modern Replacement for Date](https://www.matthewswong.com/en/blog/javascript-temporal-api-guide): The JavaScript Temporal API replaces the flawed Date with immutable types, first-class time zones, and DST-safe math. Learn the types and browser status. - [Next.js 16: Migrate middleware.ts to proxy.ts](https://www.matthewswong.com/en/blog/nextjs-16-proxy-ts-migration): How I migrated middleware.ts to proxy.ts in Next.js 16 — the rename, the codemod, why auth must move to the route layer, plus CVE-2025-29927. - [Next.js Cache Components and the use cache Directive](https://www.matthewswong.com/en/blog/nextjs-cache-components-use-cache): Learn Next.js Cache Components and the use cache directive: explicit caching, cacheLife profiles, cacheTag revalidation, and Partial Prerendering in v16. - [Next.js Hydration Errors: Causes and How to Fix Them](https://www.matthewswong.com/en/blog/nextjs-hydration-errors-fix): What the Next.js hydration failed error means, why server and client HTML diverge, and how to fix mismatches with useEffect and suppressHydrationWarning. - [Securing Next.js Server Actions: Auth, IDOR & Zod Validation](https://www.matthewswong.com/en/blog/nextjs-server-actions-security): Every Next.js Server Action is a public POST endpoint. Add per-action auth, ownership IDOR checks, Zod validation, rate limiting, and stay patched on CVEs. - [Astro 5 Server Islands & Content Layer API: What's New](https://www.matthewswong.com/en/blog/astro-5-server-islands-content-layer): How Astro 5 Server Islands mix cached static HTML with dynamic components, plus the stable Content Layer API and typed astro:env environment variables. - [Svelte 5 Runes: $state, $derived, $effect Reactivity](https://www.matthewswong.com/en/blog/svelte-5-runes-reactivity): How Svelte 5 replaces compiler-magic reactivity with explicit runes: $state, $derived, $effect, and $props, plus signals under the hood and migration. - [HTMX and the Hypermedia-Driven Application Approach](https://www.matthewswong.com/en/blog/htmx-hypermedia-driven-apps): How HTMX turns HTML attributes like hx-get and hx-swap into AJAX, why the hypermedia-driven approach rivals SPAs with less JavaScript, plus htmx 2.0. - [Tailwind CSS v4: Oxide Engine and CSS-First Config](https://www.matthewswong.com/en/blog/tailwind-css-v4-oxide-engine): Tailwind CSS v4 rebuilds the framework on the Rust Oxide engine with CSS-first theme config, automatic content detection, and up to 5x faster builds. - [React Compiler: Automatic Memoization Without useMemo](https://www.matthewswong.com/en/blog/react-compiler-automatic-memoization): The React Compiler auto-memoizes React components and hooks at build time, so you drop most useMemo, useCallback, and React.memo calls. Setup and caveats. - [Biome vs ESLint + Prettier: One Rust Toolchain to Replace Two](https://www.matthewswong.com/en/blog/biome-vs-eslint-prettier-toolchain): How Biome, a single Rust-based formatter and linter, compares to ESLint plus Prettier on speed, config, Prettier compatibility, migration, and real limits. - [Rolldown: Vite's Rust Bundler Replacing Rollup](https://www.matthewswong.com/en/blog/vite-rolldown-rust-bundler): Rolldown is the Rust bundler from the Vite team that unifies esbuild and Rollup into one toolchain. Learn why it matters and how to try rolldown-vite. - [Debouncing and Throttling in React: useDebounce Hook Guide](https://www.matthewswong.com/en/blog/debouncing-throttling-react-hooks-guide): Learn debouncing and throttling in React the right way: why naive useEffect timers leak, a reusable useDebounce hook, and proper cleanup on unmount. - [React Server Components vs Islands Architecture Guide](https://www.matthewswong.com/en/blog/react-server-components-vs-islands-architecture): React Server Components vs islands architecture in Astro and Qwik: hydration models, how each ships less JavaScript, and the real trade-offs for your app. - [TanStack Router: Type-Safe React Routing Guide](https://www.matthewswong.com/en/blog/tanstack-router-type-safe-routing): A practical guide to TanStack Router type-safe routing in React: typed params, validated search params with Zod, route loaders, and file-based routing. - [Valibot vs Zod: Bundle Size and Tree-Shaking Compared](https://www.matthewswong.com/en/blog/valibot-vs-zod-bundle-size): Valibot vs Zod for schema validation when bundle size matters: modular pipe design, tree-shaking, zod/v4-mini, and the API differences that decide it. - [React Web Workers with Comlink: Offload the Main Thread](https://www.matthewswong.com/en/blog/web-workers-offload-main-thread-react): Offload heavy CPU work in React to a Web Worker with Comlink, learn when a worker beats a server round-trip, and keep the UI rendering at 60fps. - [Zod 4 Schema Validation: Performance, Mini, Migration](https://www.matthewswong.com/en/blog/zod-4-schema-validation-performance): What changed in Zod 4: 14x faster parsing, the tree-shakable zod/mini build, unified error customization, and a practical migration path from Zod 3. - [Dynamic Open Graph Images with Next.js ImageResponse](https://www.matthewswong.com/en/blog/nextjs-dynamic-og-image-generation): Generate dynamic Open Graph images per page in Next.js using ImageResponse and Satori — custom fonts, live data, caching, and debugging OG previews. - [React Hook Form and Zod: Type-Safe Forms Guide](https://www.matthewswong.com/en/blog/react-hook-form-zod-type-safe-forms): Build end-to-end type-safe forms in Next.js using React Hook Form with a Zod resolver, shared schemas, and clean, reusable validation error handling. - [Zustand vs Redux Toolkit: Choosing React State in 2026](https://www.matthewswong.com/en/blog/zustand-vs-redux-toolkit-state): Zustand vs Redux Toolkit compared: boilerplate, devtools, bundle size, and when TanStack Query replaces global state for server data in React apps. - [Next.js Streaming SSR and Suspense: Loading UI That Feels Fast](https://www.matthewswong.com/en/blog/nextjs-streaming-suspense-patterns): Learn Next.js streaming SSR and React Suspense patterns: loading.tsx, granular boundaries, and parallel data fetching to avoid request waterfalls. - [Optimizing INP: The Core Web Vital That Replaced FID](https://www.matthewswong.com/en/blog/web-vitals-inp-optimization-2026): Fix Interaction to Next Paint (INP) by breaking up long tasks, yielding to the main thread, and measuring real-user INP scores with the web-vitals library. - [shadcn/ui Architecture: Own Your Components, Not a Dependency](https://www.matthewswong.com/en/blog/shadcn-ui-component-architecture): shadcn/ui's component architecture copies code into your repo, not a dependency, pairing Radix UI primitives with Tailwind tokens for a design system. - [TanStack Query in Next.js App Router: Prefetch and Hydrate](https://www.matthewswong.com/en/blog/tanstack-query-nextjs-app-router): Learn to prefetch TanStack Query data in Next.js App Router Server Components, hydrate it client-side with HydrationBoundary, and avoid double-fetching. - [React 19 use() Hook and Actions: A Practical Async Guide](https://www.matthewswong.com/en/blog/react-19-use-hook-actions-guide): React 19 use() and Actions guide walks through the new hooks and patterns that replace manual loading, error, and pending state boilerplate in real apps. - [Server-Sent Events in Next.js: Simpler Than WebSockets](https://www.matthewswong.com/en/blog/server-sent-events-nextjs-streaming): When Server-Sent Events beat WebSockets for real-time UI in Next.js: streaming route handlers, ReadableStream, auto reconnection, and LLM token streaming. - [Next.js Partial Prerendering: Static Shell With Streamed Holes](https://www.matthewswong.com/en/blog/nextjs-partial-prerendering-ppr): Next.js Partial Prerendering combines a static shell with streamed dynamic holes using Suspense, cutting TTFB while keeping personalized data fresh. - [Technical SEO for Developers: Canonical, hreflang, JSON-LD](https://www.matthewswong.com/en/blog/technical-seo-checklist-developers): Technical SEO checklist for developers: canonical URL strategy, bidirectional hreflang for bilingual sites, JSON-LD structured data, sitemaps, and CI verification. - [What next/image Actually Does: srcset, AVIF, and the Cache](https://www.matthewswong.com/en/blog/nextjs-image-optimization-internals): A deep dive into next/image internals: srcset generation from deviceSizes, AVIF vs WebP Accept-header negotiation, the disk cache, and four common misuse patterns. - [Design Tokens with Tailwind: A Theme That Survives a Rebrand](https://www.matthewswong.com/en/blog/design-tokens-tailwind-theme): Build a three-tier design token system with Tailwind v4 @theme: primitives, semantic aliases, DTCG format and Style Dictionary — so a rebrand edits one line. - [Self-Hosting Web Fonts for Performance: next/font Done Right](https://www.matthewswong.com/en/blog/self-hosting-web-fonts-performance): How to self-host web fonts with next/font: FOIT vs FOUT strategy, WOFF2 subsetting, variable fonts, and the metric-compatible fallback that kills CLS. - [React Server Components: The Mental Model That Finally Clicks](https://www.matthewswong.com/en/blog/react-server-components-mental-model): Understand React Server Components for real: what runs where, the module-graph boundary, the serialization wall, and a four-step rule for use client placement. - [Next.js Server Actions in Production: Forms, Validation, Security](https://www.matthewswong.com/en/blog/nextjs-server-actions-production): A production playbook for Next.js Server Actions: form pipelines with Zod and useActionState, progressive enhancement realities, and the security footguns to avoid. - [Building a Production Landing Page That Scores 100 on Core Web Vitals](https://www.matthewswong.com/en/blog/production-landing-page-core-web-vitals): A practical guide to achieving perfect Lighthouse scores on a Next.js landing page — from LCP to CLS to INP. - [TypeScript Project Structure for Real-World Apps: What Actually Works](https://www.matthewswong.com/en/blog/typescript-project-structure-real-world): Beyond the tutorials: a battle-tested folder structure and tsconfig setup for TypeScript projects that scale without becoming a maze. - [My Figma to Next.js Component Workflow](https://www.matthewswong.com/en/blog/figma-to-nextjs-component-workflow): How I translate Figma designs into production-ready Next.js components without losing fidelity or wasting time on guesswork. - [Next.js i18n with next-intl: A Complete Guide From Someone Who Actually Uses It](https://www.matthewswong.com/en/blog/nextjs-i18n-next-intl-guide): A first-hand guide to setting up next-intl in a Next.js App Router project — covering routing, server components, client components, and the gotchas I hit in production. - [Scalable Next.js Project Structure with App Router](https://www.matthewswong.com/en/blog/nextjs-project-structure-scalable): A battle-tested folder structure for Next.js 15 App Router projects that scales from side project to production SaaS. - [How to Build a SaaS in 30 Days with Next.js and Tailwind](https://www.matthewswong.com/en/blog/build-saas-30-days-nextjs-tailwind): A realistic day-by-day roadmap for solo developers to ship a working SaaS product with auth, payments, and email in one month. - [Building Type-Safe REST APIs with NestJS and Prisma](https://www.matthewswong.com/en/blog/type-safe-api-nestjs-prisma): How to wire NestJS, Prisma, and class-validator together so TypeScript type errors catch bugs before they reach production. - [SEO-First Next.js: The Complete Checklist for 2026](https://www.matthewswong.com/en/blog/seo-first-nextjs-checklist): A practical checklist covering Next.js Metadata API, Core Web Vitals, JSON-LD structured data, sitemaps, and i18n SEO in one place. - [React Query vs SWR: Which to Use in 2026](https://www.matthewswong.com/en/blog/react-query-vs-swr): A side-by-side comparison of TanStack Query and SWR for data fetching in Next.js — with real code examples for mutations, caching, and SSR. - [Real User Monitoring: Why Lab Data Lies and Field Data Wins](https://www.matthewswong.com/en/blog/real-user-monitoring-web-performance): How RUM gives you the actual performance numbers your users experience — and why Lighthouse scores alone are misleading. - [Image Optimization in Next.js: WebP, AVIF, and the Settings I Actually Ship](https://www.matthewswong.com/en/blog/image-optimization-nextjs-webp-avif): A practical guide to Next.js image optimization — the formats, the config, and the real-world results from optimizing matthewswong.com. - [Next.js Caching in 2025: ISR, SSR, and When to Use Each](https://www.matthewswong.com/en/blog/nextjs-caching-isr-ssr-strategy): A decision framework for choosing between ISR, SSR, and SSG in Next.js App Router — with real performance numbers and the configs I ship. - [Database Connection Pooling in NestJS: PgBouncer and Why You Need It](https://www.matthewswong.com/en/blog/database-connection-pooling-nestjs): How connection pooling works, why your NestJS app will eventually exhaust PostgreSQL connections, and the PgBouncer config I run in production. - [PostgreSQL Full-Text Search Without Elasticsearch: What I Use in ERP Projects](https://www.matthewswong.com/en/blog/postgresql-full-text-search-no-elasticsearch): How tsvector and GIN indexes make PostgreSQL a capable search engine for small-to-medium datasets — and when you actually need Elasticsearch. - [Cursor vs Offset Pagination: The 17x Performance Gap at Scale](https://www.matthewswong.com/en/blog/cursor-vs-offset-pagination): Why offset pagination falls apart on large datasets and how to implement cursor pagination in a NestJS API that stays fast at any page depth. - [API Versioning in NestJS: The Strategy I Actually Ship](https://www.matthewswong.com/en/blog/api-versioning-nestjs-strategy): How to implement URI-based API versioning in NestJS without breaking existing clients — with the controller patterns and migration strategy I use. - [GraphQL vs REST in 2025: Which One for Your Next Project?](https://www.matthewswong.com/en/blog/graphql-vs-rest-2025): An honest comparison of GraphQL and REST — adoption data, performance benchmarks, and the framework I use to choose between them. - [OpenAPI and Swagger in NestJS: Auto-Generated Docs That Stay Accurate](https://www.matthewswong.com/en/blog/openapi-swagger-nestjs): How to set up @nestjs/swagger so your API documentation is generated from code and never goes stale — with the decorator patterns I use. - [Environment Variables and Secrets in Next.js: What Goes Wrong and How to Fix It](https://www.matthewswong.com/en/blog/environment-variables-secrets-nextjs): The rules for NEXT_PUBLIC_ vs server-only variables, how to validate at startup, and the secrets management setup I use in production. - [E2E Testing Next.js Apps with Playwright: Setup, Patterns, and CI Integration](https://www.matthewswong.com/en/blog/e2e-testing-playwright-nextjs): How to set up Playwright for a Next.js app, write tests that don't break on every deploy, and run them in GitHub Actions CI. - [Accessibility Audit for Next.js Apps: Automating WCAG Compliance](https://www.matthewswong.com/en/blog/accessibility-audit-nextjs): How to audit Next.js apps for accessibility issues using axe-core and Playwright — with the workflow that catches 57% of WCAG violations automatically. - [npm Dependency Management and Security Auditing: What I Actually Do](https://www.matthewswong.com/en/blog/npm-dependency-management-audit): How to audit npm dependencies for vulnerabilities, manage update debt, and protect your project from supply chain attacks. - [Security Headers in Next.js: The Config I Actually Ship](https://www.matthewswong.com/en/blog/security-headers-nextjs-configuration): The complete security headers configuration for Next.js — CSP, HSTS, X-Frame-Options, and the nonce-based approach for inline scripts. - [Dark Mode in Next.js: System-Aware, Flicker-Free, and the Implementation I Ship](https://www.matthewswong.com/en/blog/dark-mode-nextjs-system-aware): How to implement dark mode in Next.js with next-themes, avoid the dreaded flash of unstyled content, and persist user preferences correctly. - [Testing Next.js Apps with Vitest and Jest: A Practical Comparison](https://www.matthewswong.com/en/blog/nextjs-testing-vitest-jest): A data-driven comparison of Vitest and Jest for Next.js applications — with benchmarks, setup examples, and an honest guide to which testing framework you should choose in 2025. - [Storybook for Component Documentation: Building a Living Design System](https://www.matthewswong.com/en/blog/storybook-component-documentation): How to use Storybook to document React components, create interactive showcases, and build a design system that stays in sync with your actual codebase. - [Next.js App Router Migration: Lessons from a Real Project](https://www.matthewswong.com/en/blog/nextjs-app-router-migration-lessons): Hard-won lessons from migrating a production Next.js app from Pages Router to App Router — what breaks, what shines, and what I'd do differently. - [Tailwind CSS vs CSS Modules: Which Should You Use in 2025?](https://www.matthewswong.com/en/blog/tailwindcss-vs-css-modules): A pragmatic comparison of Tailwind CSS and CSS Modules — download stats, DX, performance, and when each approach actually wins. - [Prisma vs TypeORM in NestJS: Which ORM Should You Choose?](https://www.matthewswong.com/en/blog/prisma-vs-typeorm-nestjs-comparison): A production-tested comparison of Prisma and TypeORM for NestJS applications — type safety, migrations, developer experience, and real npm download data. - [NextAuth vs Clerk: Authentication in Next.js Apps in 2025](https://www.matthewswong.com/en/blog/nextauth-vs-clerk-comparison): A real comparison of NextAuth.js and Clerk for Next.js authentication — pricing, DX, features, and when each makes sense for your project. - [WebSockets in NestJS: Building Real-Time Features in Production](https://www.matthewswong.com/en/blog/websockets-nestjs-realtime): A practical guide to WebSocket Gateways in NestJS with Socket.io — rooms, namespaces, Redis pub/sub for scaling, and JWT authentication. - [File Upload to S3 in Next.js: The Production Pattern](https://www.matthewswong.com/en/blog/file-upload-s3-nextjs-production): How to implement secure, scalable file uploads to AWS S3 from Next.js using presigned URLs — no files passing through your server. - [Resend vs Nodemailer: Transactional Email in 2025](https://www.matthewswong.com/en/blog/resend-vs-nodemailer-email): A practical comparison of Resend and Nodemailer for transactional email — deliverability, developer experience, pricing, and when to use each. - [Next.js API Routes vs NestJS: Choosing Your Backend in 2025](https://www.matthewswong.com/en/blog/nextjs-api-routes-vs-nestjs): A direct comparison of Next.js Route Handlers and NestJS for backend development — when each is the right tool based on real production experience. - [TypeScript Strict Mode in Production: Why It's Non-Negotiable](https://www.matthewswong.com/en/blog/typescript-strict-mode-production): Why TypeScript strict mode belongs in every production codebase — the bugs it catches, the gotchas it surfaces, and how to enable it on a legacy project. - [React Server Components: When and How to Use Them in Next.js](https://www.matthewswong.com/en/blog/react-server-components-usage): A practical guide to React Server Components in Next.js 15 — what they actually change, when to use them, and the patterns that make them powerful. - [Next.js Middleware: Real Use Cases Beyond the Docs](https://www.matthewswong.com/en/blog/nextjs-middleware-real-use-cases): Practical Next.js middleware patterns for authentication guards, i18n locale detection, A/B testing, and security headers — with code and gotchas. - [Framer Motion vs CSS Animations: When to Use Each](https://www.matthewswong.com/en/blog/framer-motion-vs-css-animations): A practical comparison of Framer Motion and pure CSS animations — bundle size, performance, DX, and my real experience using both on matthewswong.com. - [Monorepo with Turborepo: Running Next.js and NestJS Together](https://www.matthewswong.com/en/blog/monorepo-turborepo-setup): How to set up a production-ready Turborepo monorepo with Next.js frontend, NestJS backend, and shared TypeScript packages. - [API Rate Limiting in NestJS with Redis: A Production Guide](https://www.matthewswong.com/en/blog/api-rate-limiting-nestjs-redis): How to implement distributed rate limiting in NestJS using @nestjs/throttler and Redis — protecting your API from abuse at any scale. - [Next.js Error Handling Patterns: From error.tsx to Production](https://www.matthewswong.com/en/blog/nextjs-error-handling-patterns): A complete guide to error handling in Next.js App Router — error.tsx, not-found.tsx, global error boundaries, and patterns for production resilience. - [BPJS Ketenagakerjaan API Integration: Payroll Developer Guide](https://www.matthewswong.com/en/blog/bpjs-api-integration): A guide to BPJS API integration for Indonesian payroll: HMAC authentication, 2026 contribution rates, JKP, and the PKS approval process for developers. ## Blog — AI & LLMs - [A2A vs MCP: Which AI Agent Protocol Do You Actually Need?](https://www.matthewswong.com/en/blog/a2a-vs-mcp-agent-protocols): A2A vs MCP compared: agent-to-tool versus agent-to-agent, discovery, stateless MCP, MCP Tasks versus A2A tasks, auth and governance, plus one architecture. - [AI Agent Cost Optimization: Budget Per Task, Not Per Call](https://www.matthewswong.com/en/blog/ai-agent-cost-per-task-budgets): AI agent cost optimization: measure cost per completed task, cap max_turns, limit subagents, defer tools, compact context and route models. IDR example. - [AI Agent Evaluation: How to Test Tool Calls and Trajectories](https://www.matthewswong.com/en/blog/ai-agent-evals-trajectory-testing): AI agent evaluation that grades the trajectory: tool selection, arguments, call order, goal success and cost, with promptfoo assertions on a NestJS agent. - [ChatGPT Plugins (Apps SDK) Guide: Build an ERP Plugin on MCP](https://www.matthewswong.com/en/blog/chatgpt-plugins-apps-sdk-mcp-guide): ChatGPT plugins, the Apps SDK renamed: build an MCP server, an MCP Apps UI and a skill for an ERP order lookup, then pass Plugin Directory submission. - [Claude Managed Agents vs OpenAI Agents API: Full Comparison](https://www.matthewswong.com/en/blog/claude-managed-agents-vs-openai-agents-api): Claude Managed Agents vs OpenAI Agents API compared: sessions, sandboxes, custom tools, cron scheduling, ZDR, data residency and pricing for hosted agents. - [Google ADK 2.0 Tutorial: Graph Workflows and Multi-Agents](https://www.matthewswong.com/en/blog/google-adk-2-graph-workflows-tutorial): Google ADK 2.0 tutorial: build a procurement approval graph workflow with routes, human-in-the-loop pauses, persistent sessions, evals and 1.x migration. - [LangChain create_agent Middleware Guide: PII, Limits, Fallback](https://www.matthewswong.com/en/blog/langchain-create-agent-middleware-guide): LangChain create_agent middleware in practice: migrate from create_react_agent, add PII redaction, tool-call limits, model fallback and human approval. - [LangGraph vs CrewAI in 2026: Which for Production Agents?](https://www.matthewswong.com/en/blog/langgraph-vs-crewai-production-agents): LangGraph vs CrewAI for production agents: graph vs crews and flows, durable execution, human approval and resume, compared on one invoice workflow. - [Mastra TypeScript Agent Framework Tutorial: Workflows and Evals](https://www.matthewswong.com/en/blog/mastra-typescript-agent-framework-tutorial): Mastra TypeScript agent framework tutorial: build agents with Zod tools, suspendable workflows, evals and Studio, wired into a Next.js ERP app. - [Microsoft Agent Framework 1.0: Semantic Kernel Migration Guide](https://www.matthewswong.com/en/blog/microsoft-agent-framework-semantic-kernel-migration): Microsoft Agent Framework 1.0 migration from Semantic Kernel and AutoGen: concept map, C# and Python code, harness approvals, compaction and CodeAct. - [OpenAI Agent Builder Shutdown: Migrate Before Nov 30, 2026](https://www.matthewswong.com/en/blog/openai-agent-builder-shutdown-migration): OpenAI Agent Builder shutdown lands on 30 November 2026. Inventory each workflow, rebuild it in the Agents SDK or a Workspace Agent, and prove parity. - [OpenAI Agents API Tutorial: Hosted Agents and Sandboxes](https://www.matthewswong.com/en/blog/openai-agents-api-hosted-sandbox-tutorial): OpenAI Agents API tutorial in TypeScript: create a session in a hosted sandbox, stream events, steer mid-turn, handle webhooks, then clean up safely. - [OpenAI Agents API vs Agents SDK vs Responses API: Which?](https://www.matthewswong.com/en/blog/openai-agents-api-vs-agents-sdk): OpenAI Agents API vs Agents SDK vs Responses API vs ChatKit: who owns the agent loop, where state lives, ZDR, data residency, cost and lock-in, compared. - [OpenAI Agents SDK Guardrails: Input, Output and Tool Checks](https://www.matthewswong.com/en/blog/openai-agents-sdk-guardrails-tripwires): OpenAI Agents SDK guardrails explained: input, output and tool tripwires, parallel vs blocking mode, the exceptions to catch, and where checks never run. - [OpenAI Agents SDK Handoffs vs Agents as Tools Explained](https://www.matthewswong.com/en/blog/openai-agents-sdk-handoffs-vs-agents-as-tools): OpenAI Agents SDK handoffs pass the chat to a specialist; agent.as_tool() keeps control. Compare history, guardrails and tracing in an ERP helpdesk. - [OpenAI Agents SDK Sandbox Agents: Manifest, Docker, E2B](https://www.matthewswong.com/en/blog/openai-agents-sdk-sandbox-agents-manifest): OpenAI Agents SDK sandbox agents explained: SandboxAgent, the Manifest, Docker and E2B clients, snapshots, and why Unix-local gives you no isolation. - [OpenAI Agents SDK Sessions: SQLite, Redis and Postgres Memory](https://www.matthewswong.com/en/blog/openai-agents-sdk-sessions-redis-sqlalchemy): OpenAI Agents SDK sessions compared: SQLiteSession, RedisSession, SQLAlchemySession on Postgres and Conversations, with compaction and encryption wrappers. - [OpenAI Agents SDK TypeScript Tutorial: Build a Tool Agent](https://www.matthewswong.com/en/blog/openai-agents-sdk-typescript-tutorial): Build an OpenAI Agents SDK TypeScript agent: zod tools, hosted file search, a handoff, Next.js streaming, a maxTurns cap and promptfoo trajectory tests. - [OpenAI Agents SDK vs Google ADK vs Claude Agent SDK (2026)](https://www.matthewswong.com/en/blog/openai-agents-sdk-vs-google-adk-vs-claude-agent-sdk): OpenAI Agents SDK vs Google ADK vs Claude Agent SDK in 2026: languages, multi-agent models, sandboxes, sessions, tracing, evals and hosted runtimes. - [OpenAI ChatKit Tutorial: Self-Hosted Agent Chat in React](https://www.matthewswong.com/en/blog/openai-chatkit-self-hosted-chat-ui): OpenAI ChatKit tutorial: embed agent chat in React with @openai/chatkit-react and a self-hosted Python ChatKit server, plus widgets, attachments and auth. - [OpenAI DevDay 2026 for Developers: Sol, Ultrafast, Agents API](https://www.matthewswong.com/en/blog/openai-devday-2026-developer-announcements): OpenAI DevDay 2026 for developers: GPT-6.1 Sol pricing, the 6x Ultrafast tier, Agents API computer use, Decisions API and Codex, plus a plan to act on. - [OpenAI Dots Agents Explained: Always-On ChatGPT Agents](https://www.matthewswong.com/en/blog/openai-dots-always-on-chatgpt-agents): OpenAI Dots agents explained: GPT-6 Astra, a cloud computer per dot, Custom Rules, Auto-review, plans and limits, and piloting one in an ERP back-office. - [OpenAI Evals Shutdown: Migrate Your Evals to Promptfoo](https://www.matthewswong.com/en/blog/openai-evals-shutdown-promptfoo-migration): OpenAI Evals shutdown guide: evals go read-only on 31 October 2026. Export definitions, runs and datasets, then rebuild them as a promptfoo suite in CI. - [OpenAI Realtime Voice Agent over SIP with gpt-realtime-2.1](https://www.matthewswong.com/en/blog/openai-realtime-voice-agent-sip-phone): Build an OpenAI realtime voice agent on gpt-realtime-2.1 with the Agents SDK: tools, handoffs, guardrails, a SIP phone line, GA migration and real costs. - [OpenAI Responses API Remote MCP: Approvals, Filters, Tunnels](https://www.matthewswong.com/en/blog/openai-responses-remote-mcp-approvals): OpenAI Responses API remote MCP, done safely: server_url or Secure MCP Tunnel, allowed_tools, require_approval policies and OAuth tokens on every request. - [OpenAI Skills API: SKILL.md Bundles in the Hosted Shell](https://www.matthewswong.com/en/blog/openai-skills-api-hosted-shell): The OpenAI Skills API uploads versioned SKILL.md bundles to /v1/skills and mounts them in the hosted shell, with allowlists and domain_secrets for safety. - [Playwright MCP vs Browser Use vs Stagehand: Browser Agents](https://www.matthewswong.com/en/blog/playwright-mcp-vs-browser-use-vs-stagehand): Playwright MCP vs Browser Use vs Stagehand vs computer-use tools: who owns the agent loop, DOM or screenshots, repeat-run cost and safety in 2026. - [WhatsApp AI Agent Indonesia: UMKM Order Bot with Agents SDK](https://www.matthewswong.com/en/blog/whatsapp-ai-agent-umkm-indonesia): Build a WhatsApp AI agent in Indonesia for UMKM orders: Cloud API webhook, Agents SDK stock tools, per-number sessions and a human handover kept free. - [Bahasa Indonesia LLM Token Cost: 1.23x, Not 2-3x, Measured](https://www.matthewswong.com/en/blog/bahasa-indonesia-llm-token-cost): Bahasa Indonesia LLM token cost, measured on 20 matched sentence pairs: 1.23x English on o200k_base, down from 1.52x, not the 2-3x repeated online. - [RAG Bahasa Indonesia: Postgres Full-Text Search Misses Docs](https://www.matthewswong.com/en/blog/rag-bahasa-indonesia-search-retrieval): RAG retrieval in Bahasa Indonesia fails quietly: Postgres keeps every stop word and mis-stems me- verbs. Measured on 16.11, with the SQL that fixes it. - [Speech-to-Text Bahasa Indonesia in Production: Real Whisper WER](https://www.matthewswong.com/en/blog/speech-to-text-bahasa-indonesia-production): Published Indonesian speech-to-text WER by benchmark, why code-switching breaks Whisper, and how to choose between self-hosted Whisper and managed APIs. - [How ChatGPT Astra Built My 3D Portfolio Game, Step by Step](https://www.matthewswong.com/en/blog/chatgpt-astra-3d-portfolio-game-archipelago): A 1,015-line PRD, six gated phases and a headless screenshot loop: how ChatGPT Astra built The Archipelago, a React Three Fiber portfolio game. - [Indonesia Grok Block: AI Image Moderation for Product Builders](https://www.matthewswong.com/en/blog/indonesia-grok-block-ai-moderation-lesson): Indonesia blocked Grok in January 2026 over non-consensual deepfakes. The AI image moderation layers a builder owes: intake, refusal tests, C2PA, takedown. - [Sahabat AI: Indonesian LLM Developer Guide and Token Costs](https://www.matthewswong.com/en/blog/sahabat-ai-indonesian-llm-developer-guide): Sahabat AI is an Indonesian LLM from GoTo and Indosat. I measured tokens per word across four tokenisers to find when a local model beats a frontier API. - [Onboarding an AI Coding Agent to an Unfamiliar Codebase](https://www.matthewswong.com/en/blog/ai-agent-onboarding-unfamiliar-codebase): Onboarding an AI coding agent to an unfamiliar codebase in one hour: map the perimeter, run the commands, and trace every claim to a file and a line. - [Prompt Regression Testing in CI: Assert a Rate, Not an Answer](https://www.matthewswong.com/en/blog/prompt-regression-testing-ci-evals): Prompt regression testing in CI: build fixtures from real bugs, assert deterministically before any judge, pin the model, and score a rate, not one run. - [Deterministic Hooks vs Agent Judgement in Claude Code](https://www.matthewswong.com/en/blog/deterministic-hooks-vs-agent-judgement): A hook always fires; an instruction is only sometimes followed. How I decide which Claude Code rules become deterministic hooks and which stay judgement. - [LLM Token Budget for a Small Engineering Team: Where It Goes](https://www.matthewswong.com/en/blog/llm-token-budget-engineering-team): An agentic coding bill scales with the context you re-send, not the code you generate. Where a small team's LLM token budget goes, and what to measure. - [AI Code Review as a CI Merge Gate: What Should Block](https://www.matthewswong.com/en/blog/ai-code-review-merge-gate-ci): AI code review merge gate: which findings may block a pull request in CI, which stay advisory, and how to measure precision in shadow mode first. - [Context Engineering for AI Coding Agents in a Monorepo](https://www.matthewswong.com/en/blog/context-engineering-monorepo-ai-agents): A monorepo defeats naive agent context. Scope instruction files by directory, activate skills by glob, and delegate fan-out search to a subagent window. - [A2A Protocol: How AI Agents Discover and Delegate to Peers](https://www.matthewswong.com/en/blog/a2a-protocol-agent-interoperability): A2A protocol explained for ERP developers: Agent Cards, opaque peers, and the task states that admit an AI agent delegation has stalled on a human. - [Indonesia AI Adoption: Is the Country on the Right Path?](https://www.matthewswong.com/en/blog/indonesia-ai-adoption-right-path): Indonesia AI adoption is ahead at the individual layer and stuck at the institutional one: 69 percent of workers use AI, 26 percent of firms deploy it. - [Go and TypeScript: Strict Types for AI-Assisted Coding](https://www.matthewswong.com/en/blog/go-typescript-ai-assisted-coding): Why strict, statically typed languages like Go and TypeScript suit AI-assisted coding: a compiler feedback loop lets agents self-correct before code runs. - [Claude Code Advisor Tool: A Second Model at Key Moments](https://www.matthewswong.com/en/blog/claude-code-advisor-tool-second-opinion): The advisor lets Claude consult a stronger model at decision points instead of running it all the time. Here are the pairings, cost and limits. - [Claude Code Auto Memory: What Claude Remembers and Why](https://www.matthewswong.com/en/blog/claude-code-auto-memory-recall): Auto memory is notes Claude writes itself from your corrections. Here is what it saves, where it lives, the index limit, and how to audit it. - [Claude Code Fast Mode and Effort Levels: Speed vs Cost](https://www.matthewswong.com/en/blog/claude-code-fast-mode-effort-levels): Fast mode is the same Opus configured for speed at a higher token price. Here is when it pays, the cost trap, and how effort levels differ from it. - [Claude Code goal Command: Turns Until a Condition Holds](https://www.matthewswong.com/en/blog/claude-code-goal-command-autonomous-loop): The goal command sets a completion condition and a second model checks it after every turn. Here is how to write one that actually resolves. - [Claude Code Plugin Dependencies and Version Constraints](https://www.matthewswong.com/en/blog/claude-code-plugin-dependencies-versioning): An unconstrained plugin dependency tracks the latest release. Here are semver ranges, the git tag convention that resolves them, and bundles. - [Claude Code Plugin Marketplace: Authoring marketplace.json](https://www.matthewswong.com/en/blog/claude-code-plugin-marketplace-authoring): A marketplace is one JSON file that distributes Claude Code plugins. Here are its sources, the version trap that strands users, and team rollout. - [Claude Code Background Agents: The Supervisor Model](https://www.matthewswong.com/en/blog/claude-code-agent-view-background-sessions): Background sessions live in a per-user supervisor that outlives your shell. That one fact explains the worktrees, the credentials and the surprises. - [Claude Code Channels: Push Events Into a Live Session](https://www.matthewswong.com/en/blog/claude-code-channels-external-events): A channel is an MCP server that pushes rather than waits, so CI failures and chat messages reach the session that already has your files open. - [Claude Code Ultrareview: A Verified Multi-Agent Review](https://www.matthewswong.com/en/blog/claude-code-code-review-ultrareview): Ultrareview runs a fleet of reviewers in a cloud sandbox and reproduces every finding before reporting it. Here is what that costs and catches. - [Claude Code in Chrome: Browser Automation From the CLI](https://www.matthewswong.com/en/blog/claude-code-chrome-browser-automation): Chrome integration shares your browser's logged-in state, which is what makes it powerful and what you have to reason about. Here is the permission model. - [Claude Code 1M Context: When It Helps and When It Hurts](https://www.matthewswong.com/en/blog/claude-code-1m-context-window-strategy): A million-token window changes when compaction fires, not whether you need it. Here is who gets it, how to size it, and when capping it is the better call. - [Claude Code Cross-Session Messaging: Sessions That Talk](https://www.matthewswong.com/en/blog/claude-code-cross-session-messaging): One Claude Code session can message another by name, on this machine or across yours. Here is the addressing, the inbound controls and the trust model. - [Claude Code Model Config: Aliases, Fallbacks, Effort](https://www.matthewswong.com/en/blog/claude-code-model-config-fallback-picker): Model aliases resolve differently per provider, fallback chains stay invisible until they fire, and effort levels degrade silently. Here is the picture. - [Claude Code Prompt Caching: Tune the TTL, Cut the Bill](https://www.matthewswong.com/en/blog/claude-code-prompt-caching-ttl-tuning): Claude Code caches by exact prefix match, so a mid-task model switch costs a full re-read. Here are the two TTL buckets and what silently invalidates them. - [Claude Code Tool Search: Defer MCP Tools, Save Context](https://www.matthewswong.com/en/blog/claude-code-tool-search-deferred-tools): Tool search loads MCP tool names at startup and fetches schemas on demand. Here is ENABLE_TOOL_SEARCH, alwaysLoad, and the prompt-cache win. - [Claude Code Agent Teams: Parallel Multi-Agent Workflows](https://www.matthewswong.com/en/blog/claude-code-agent-teams-guide): How Claude Code agent teams spawn teammates with their own context windows, message each other through a mailbox, and share one locked task list. - [Claude Code Dynamic Workflows: Orchestrate 1,000 Agents](https://www.matthewswong.com/en/blog/claude-code-dynamic-workflows-orchestration): Dynamic workflows move the orchestration into a JavaScript script. Here is the API, the pipeline versus barrier trade, the caps, and what resume keeps. - [Claude Code Remote Control: Drive Local Sessions Remotely](https://www.matthewswong.com/en/blog/claude-code-remote-control-mobile-sessions): Remote Control makes your phone a window into a Claude Code process on your own machine. Here is server mode, the security model, and what blocks it. - [Claude Code Usage Data: What 400,000 Sessions Reveal](https://www.matthewswong.com/en/blog/claude-code-usage-statistics-research-2026): Anthropic studied 400,000 Claude Code sessions. The findings on expertise, verified success and the 70/20 decision split change how you should work. - [Free-Tier Model Fallback Chains for an Autonomous Agent](https://www.matthewswong.com/en/blog/hermes-agent-free-tier-model-fallback-chain): Every stage of a fallback chain must be a separate quota bucket. Lessons from running a daily coding agent entirely on free model tiers for a month. - [Autonomous Agent Prompt Design: Tiny Commits That Land](https://www.matthewswong.com/en/blog/hermes-agent-prompt-design-tiny-commits): Why an open-ended daily brief produces zero commits, and the numbered procedure — first commit by turn six, land by turn thirty — that produced merged PRs. - [Give an Autonomous Coding Agent Memory: KNOWLEDGE + RAG](https://www.matthewswong.com/en/blog/autonomous-agent-knowledge-rag-loop): Three markdown files, a stdlib vector search and a reflection step: how a daily coding agent stopped repeating mistakes and started compounding knowledge. - [Claude Code MCP Server Setup: Scopes, Auth, Tool Budget](https://www.matthewswong.com/en/blog/claude-code-mcp-server-setup-governance): Add MCP servers to Claude Code without wrecking context or security: the three scopes, transports, tool search, workspace trust and prompt injection. - [Claude Code Context Window: Compaction and Token Control](https://www.matthewswong.com/en/blog/claude-code-context-window-compaction): Why long Claude Code sessions get expensive, what auto-compaction really does, and six habits that keep the context window small without losing work. - [Claude Code in a Monorepo: Scoped CLAUDE.md and Skills](https://www.matthewswong.com/en/blog/claude-code-monorepo-workflow): Layered memory files, package-level conventions, skills for procedures and git worktrees for parallel agents — running Claude Code in a large monorepo. - [Claude Code Content Pipeline for a Bilingual Next.js Blog](https://www.matthewswong.com/en/blog/claude-code-bilingual-blog-content-pipeline): A staging folder, a validate-then-write merge script and build-time parity guards: how agent-written bilingual posts ship safely on a Next.js blog. - [Best Terminal AI Coding Agents in 2026](https://www.matthewswong.com/en/blog/best-terminal-ai-coding-agents-2026): The best terminal AI coding agents in 2026 compared: Claude Code, OpenAI Codex CLI, and Aider, what each is best at, and how to pick the right one for you. - [Fan-Out vs Pipeline: AI Agent Patterns](https://www.matthewswong.com/en/blog/fan-out-vs-pipeline-agent-pattern): Fan-out vs pipeline agent pattern compared: parallel breadth versus sequential depth, their cost and failure trade-offs, and how to combine them by phase. - [How to Write a CLAUDE.md That Improves AI Output](https://www.matthewswong.com/en/blog/writing-claude-md-memory-guide): Learn CLAUDE.md best practices: what belongs in the memory file, where the files actually live, and how to keep it lean with progressive disclosure. - [Best Claude Code Plugins 2026: 62 Agentic Workflow Tools](https://www.matthewswong.com/en/blog/claude-code-plugins-marketplace-guide): The best Claude Code plugins for 2026: 62 open-source skills, subagents, and hooks for agentic coding, code review, security, and governance. - [Claude Code Plan Mode: Ship Fewer Broken PRs](https://www.matthewswong.com/en/blog/claude-code-plan-mode-guide): Learn how Claude Code Plan Mode makes the agent explore and plan read-only before it writes code, so you catch wrong approaches before broken PRs. - [Claude Code vs Cursor vs Copilot: 2026 Compared](https://www.matthewswong.com/en/blog/claude-code-vs-cursor-vs-copilot): Claude Code vs Cursor vs Copilot in 2026: how form factor, autonomy, context control, and cost differ, and how to pick the AI coding tool that fits you. - [Claude Code Skills: Author On-Demand Procedures](https://www.matthewswong.com/en/blog/claude-code-skills-authoring-guide): Learn how to author Claude Code skills: write a SKILL.md the model invokes on its own, use progressive disclosure, and package reusable procedures. - [Claude Code Subagents: Setup and Workflow Guide](https://www.matthewswong.com/en/blog/claude-code-subagents-setup-guide): Learn how Claude Code subagents work: define them in .claude/agents/, scope their tools, delegate review and research, and control token cost. - [Agentic Coding Workflow: Best Practices for AI Agents](https://www.matthewswong.com/en/blog/agentic-coding-workflow-best-practices): An agentic coding workflow that actually works: give the agent durable context, scope small tasks, run tests in the loop, and verify before shipping. - [AI Agent vs LLM: What Is the Difference?](https://www.matthewswong.com/en/blog/ai-agent-vs-llm-model): AI agent vs LLM explained for developers: an LLM predicts text in one stateless call, while an AI agent wraps a model in a loop with tools and memory. - [Claude Code vs Codex: Agentic Coding Compared](https://www.matthewswong.com/en/blog/claude-code-vs-codex-agentic-coding): Claude Code vs Codex CLI compared: vendors, underlying models, open source, permissions, MCP support, and config files CLAUDE.md and AGENTS.md. - [DeepSeek V4 Flash: Building a Spider-Man Cafe Tracker](https://www.matthewswong.com/en/blog/deepseek-v4-flash-cafe-tracker): I built Cafe Tracker, a Spider-Man Brand New Day style live map of cafes around BSD and Gading Serpong, using DeepSeek V4 Flash 0731. Here is how it went. - [How Claude Code Works: Agentic Coding Explained](https://www.matthewswong.com/en/blog/how-claude-code-works-agentic-coding): How Claude Code works: a terminal-native AI agent that reads files, edits code, runs commands, and searches your repo in a plan-act-observe loop. - [Human-in-the-Loop Design for AI Agents](https://www.matthewswong.com/en/blog/human-in-the-loop-ai-agents): How to design human-in-the-loop AI agents: approval gates, least-privilege permissions, plan review, spend caps and audit logs to gate risky actions. - [MCP OAuth: Why Authentication for AI Agents Is Hard](https://www.matthewswong.com/en/blog/mcp-oauth-authentication-hard): MCP OAuth is hard because a remote MCP server is an OAuth resource server needing PKCE, dynamic client registration, and RFC 8707 audience binding. - [MCP vs Function Calling: How AI Agents Use Tools](https://www.matthewswong.com/en/blog/mcp-vs-function-calling): MCP vs function calling explained: function calling is a model API feature for tool use, while MCP is an open protocol that makes those tools reusable. - [Multi-Agent Orchestration: Subagents Explained](https://www.matthewswong.com/en/blog/multi-agent-orchestration-subagents-workflow): Multi-agent orchestration splits agentic work across subagents with isolated context windows, letting a lead agent run parallel research and analysis. - [Spec-Driven Development With AI Coding Agents](https://www.matthewswong.com/en/blog/spec-driven-development-ai-agents): Spec-driven development gives AI coding agents a written spec to build against, turning fuzzy prompts into checkable acceptance criteria you can verify. - [Cloudflare Wallets: Programmable Payments for AI Agents](https://www.matthewswong.com/en/blog/cloudflare-wallets-agentic-payments): Cloudflare Wallets lets AI agents pay for APIs and content over HTTP using x402 and stablecoins, with human spending caps. Here is what was announced. - [Claude Code Slash Commands: Automate Your Prompts](https://www.matthewswong.com/en/blog/claude-code-slash-commands-guide): Learn how Claude Code slash commands turn repeated prompts into reusable Markdown files with arguments, tool scoping, and live shell output. - [Claude Code Output Styles: Custom System Prompts](https://www.matthewswong.com/en/blog/claude-code-output-styles-guide): Claude Code output styles let you replace the built-in system prompt. Learn the three presets, how to author custom styles, and when to use each one. - [How to Fix AI Agent Infinite Handoff Loops](https://www.matthewswong.com/en/blog/ai-agent-handoff-loops-fix): Fix the AI agent handoff loop where agents bounce a task forever. Use one orchestrator, clear ownership, and hard iteration caps to end the run cleanly. - [Claude Code Hooks: Deterministic Agent Guardrails](https://www.matthewswong.com/en/blog/claude-code-hooks-guardrails-guide): Learn how Claude Code hooks turn lifecycle events into deterministic guardrails: auto-format edits, block risky writes, and gate tasks on passing tests. - [Claude Code Checkpointing: Rewind Risky Changes](https://www.matthewswong.com/en/blog/claude-code-checkpointing-rewind-guide): How Claude Code checkpointing and rewind work: snapshot code before each edit, undo a bad agent change with a double Escape, and its limits versus git. - [Claude Code Cost Optimization: Cut Token Spend](https://www.matthewswong.com/en/blog/claude-code-cost-optimization-guide): Claude Code cost optimization made practical: cut token spend with lean context, model matching, subagent delegation, and per-session cost tracking. - [AI Writer-Reviewer Pattern for Coding Agents](https://www.matthewswong.com/en/blog/ai-writer-reviewer-agent-pattern): Learn the AI writer reviewer agent pattern: one agent drafts code, a second reviews the diff in a fresh context, and the loop catches bugs before you do. - [Claude Code Skills vs Hooks vs Subagents vs MCP](https://www.matthewswong.com/en/blog/claude-code-skills-vs-hooks-vs-subagents): Claude Code skills vs hooks vs subagents vs MCP: what each mechanism does, when it runs, and how to match the right one to your task on the first try. - [Context Engineering for LLM Agents: Write, Select, Compress](https://www.matthewswong.com/en/blog/context-engineering-llm-agents): Context engineering superseded prompt engineering for LLM agents in 2025. Learn the write, select, compress, isolate strategies and context failure modes. - [Run Local LLMs with Ollama: Models, API, and Modelfile](https://www.matthewswong.com/en/blog/ollama-run-local-llms): How I run open-weight LLMs like Llama, Gemma, and Qwen locally with Ollama: one command to pull a model, an OpenAI-compatible API, and full data privacy. - [Vercel AI SDK 5 Guide: Type-Safe Chat, Tools & Agents](https://www.matthewswong.com/en/blog/vercel-ai-sdk-5-guide): A hands-on guide to Vercel AI SDK 5 for TypeScript: the UIMessage vs ModelMessage split, agentic loop control, tool calling, streaming, and useChat. - [llms.txt Explained: The AI Standard for Website Content](https://www.matthewswong.com/en/blog/llms-txt-ai-website-standard): llms.txt is a Markdown file that maps your site for LLMs. Learn the spec, real adoption, and why Google's John Mueller stays skeptical in 2026. - [Building a Streaming Chatbot with Groq and Next.js](https://www.matthewswong.com/en/blog/groq-nextjs-streaming-chatbot): Learn to build a fast streaming chatbot with the Groq API and Next.js route handlers, covering system prompts, rate limiting, and cost control. - [Document Data Extraction with Multimodal LLMs: A Guide](https://www.matthewswong.com/en/blog/multimodal-llm-document-data-extraction): Extract structured data from PDFs and scans using multimodal LLMs, with prompt design, bounding-box grounding, confidence scoring, and human review. - [Semantic Caching for LLMs: Cut API Costs on Repeat Prompts](https://www.matthewswong.com/en/blog/semantic-caching-llm-cost-reduction): Learn how semantic caching for LLMs uses embedding similarity to cut API costs on repeat questions, with threshold tuning and invalidation tips. - [Building Production Agents with the Claude Agent SDK](https://www.matthewswong.com/en/blog/claude-agent-sdk-building-agents): A practitioner's guide to the Claude Agent SDK: the agent loop, tool permissions, subagents, and shipping a production coding or ops agent today. - [LLM Evals in CI: Testing Prompts Like Code](https://www.matthewswong.com/en/blog/llm-evaluation-testing-ci-pipeline): Build an LLM evaluation pipeline in CI with golden datasets, code and LLM-judge scoring, and regression gates that catch prompt drift before shipping. - [LLM Structured Output: JSON Schema That Actually Validates](https://www.matthewswong.com/en/blog/llm-structured-output-json-schema): Get reliable LLM structured output with JSON Schema and tool-based constraints in TypeScript: handle refusals, truncation, and validate results with Zod. - [Claude Fable 5: What Developers Need to Know](https://www.matthewswong.com/en/blog/claude-fable-5-developers-guide): A practitioner's guide to Claude Fable 5: pricing vs Opus and Sonnet, always-on thinking, the API parameters that now return 400, and when to use it. - [AI Agents in Production: Lessons from a Year of Agentic Workflows](https://www.matthewswong.com/en/blog/ai-agents-production-lessons): Practical lessons for production AI agents: workflows vs agents, tool design rules, layered guardrails, eval loops in CI, and ops-grade observability. - [AI Product Description Generator SaaS for Sellers](https://www.matthewswong.com/en/blog/ai-product-description-saas-indonesia): Build an AI product description generator SaaS for Tokopedia and Shopee sellers in Indonesia: architecture, prompt design, token costs, and real margins. - [MCP Explained: What the Model Context Protocol Actually Solves](https://www.matthewswong.com/en/blog/mcp-model-context-protocol-explained): The Model Context Protocol from the ground up: hosts, clients, servers, the three primitives, and an honest framework for when to build your own MCP server. - [How I Combine Opus 4.7 and Sonnet 4.6 in Claude Code](https://www.matthewswong.com/en/blog/claude-opus-4-7-whats-new): A practical Claude Code workflow: Opus 4.7 for planning and critical reasoning, Sonnet 4.6 for efficient task execution. - [LLM Prompt Caching: The Cheapest Cost Optimization You Are Not Using](https://www.matthewswong.com/en/blog/llm-prompt-caching-cost-optimization): Prompt caching economics compared across Anthropic, OpenAI, and Gemini: write premiums, TTLs, minimums, and how to architect cache-friendly prompts. - [Hermes AI Agent by Nous Research: Architecture, Self-Learning Loop, and Getting Started](https://www.matthewswong.com/en/blog/hermes-ai-agent-nousresearch-guide): A deep dive into Hermes — the open-source AI agent framework with a closed self-learning loop, persistent memory, 40+ tools, and multi-platform deployment via a single gateway. - [MCP Authorization with Cerbos: Policy-as-Code for AI Agents](https://www.matthewswong.com/en/blog/mcp-auth-cerbos-authorization): How to use Cerbos's open-source policy engine to control which tools your MCP server exposes per user role — without hard-coding ACLs. - [How I Cut My LLM API Bill by 60% Without Touching Model Quality](https://www.matthewswong.com/en/blog/llm-api-cost-optimization): Practical strategies for reducing LLM API costs in production — from prompt caching to model routing — with real numbers from my AI Gymbro project. - [AI Agent Workflow Automation in 2025: What Actually Works](https://www.matthewswong.com/en/blog/ai-agent-workflow-automation-2025): A practical guide to building reliable AI agent workflows — the patterns that work in production and the pitfalls that will waste your time. - [RAG Pipeline Production Lessons: What Nobody Tells You](https://www.matthewswong.com/en/blog/rag-pipeline-production-lessons): Hard-won lessons from building production RAG systems — indexing strategy, chunking failures, retrieval quality, and the metrics that actually matter. - [Claude API Tool Use in Production: A Real-World Guide](https://www.matthewswong.com/en/blog/claude-api-tool-use-production): Everything I learned shipping Claude's tool use (function calling) in production — schema design, error handling, streaming, and cost management. - [OpenAI vs Anthropic vs Google Gemini: A Developer's Honest Comparison (2025)](https://www.matthewswong.com/en/blog/openai-vs-anthropic-vs-gemini-developers): A practical comparison of the three major LLM APIs from a developer who has used all three in production — pricing, DX, reliability, and when to use each. - [LangChain vs Building Your Own LLM Orchestration: When to Use Each](https://www.matthewswong.com/en/blog/langchain-vs-custom-llm): An honest assessment of LangChain in 2025 — when it saves time, when it gets in the way, and how to decide if you need it at all. - [AI-Powered Code Review with GitHub Actions: My Setup](https://www.matthewswong.com/en/blog/ai-code-review-github-actions): How to add AI code review to your GitHub PR workflow — tool choices, prompt engineering, cost management, and what AI actually catches vs. misses. - [pgvector vs Pinecone vs Qdrant: Choosing Your Vector Database in 2025](https://www.matthewswong.com/en/blog/pgvector-vs-pinecone-comparison): A practical comparison of the top vector database options — performance benchmarks, pricing, and which one to choose for your specific use case. - [Prompt Engineering for Production: Beyond the Basics](https://www.matthewswong.com/en/blog/prompt-engineering-production): Production prompt engineering is different from tutorial prompt engineering — version control, testing, regression prevention, and the patterns that actually improve reliability. - [AI Content Generation Quality Control: What I Learned the Hard Way](https://www.matthewswong.com/en/blog/ai-content-generation-quality): Using AI to generate content at scale without sacrificing quality — the review workflows, quality signals, and failure modes you need to know about. - [Prompt Injection Defense: How I Harden AI Systems Against Manipulation](https://www.matthewswong.com/en/blog/ai-prompt-injection-defense): Real prompt injection attack patterns, OWASP LLM Top 10 defenses, and practical controls I implement when building AI-powered APIs and agents. - [Building an MCP Server from Scratch: A Practical Developer Guide](https://www.matthewswong.com/en/blog/mcp-server-development-guide): Step-by-step guide to building a Model Context Protocol server with real tools, authentication, and production deployment — using the official TypeScript SDK. - [AI Agent Memory Persistence Patterns: From Volatile to Long-Term](https://www.matthewswong.com/en/blog/ai-agent-memory-persistence-patterns): How to implement memory for AI agents — covering in-context, external vector store, and structured database patterns with real trade-offs from production deployments. - [Running Local LLMs with Ollama in Production: What I Learned](https://www.matthewswong.com/en/blog/local-llm-ollama-production): A practical guide to deploying Ollama for production local LLM inference — covering model selection, hardware requirements, API integration, and when local beats cloud. - [AI Observability: How to Log, Trace, and Monitor LLM Applications](https://www.matthewswong.com/en/blog/ai-observability-llm-logging): Production LLM observability with Langfuse, token cost tracking, latency monitoring, and anomaly detection — lessons from running AI-powered ERP integrations. - [Function Calling Patterns: OpenAI vs Anthropic Tool Use in Production](https://www.matthewswong.com/en/blog/function-calling-openai-anthropic): Compare OpenAI function calling and Anthropic tool use APIs — with real patterns for parallel calls, error handling, retry logic, and structured output extraction. ## Blog — AI / Machine Learning - [Hybrid Search and Reranking: Boosting RAG Retrieval](https://www.matthewswong.com/en/blog/hybrid-search-reranking-rag): Improve RAG accuracy with hybrid search: fuse BM25 and vector retrieval via reciprocal rank fusion, then rerank with cross-encoders before generation. - [Embedding Model Selection: A Practical RAG Benchmark Guide](https://www.matthewswong.com/en/blog/embedding-model-selection-benchmark): Compare embedding models for RAG on dimensions, cost, and multilingual recall, with MTEB leaderboard caveats and a benchmark script for your own data. - [Semantic Search with pgvector: Skip the Dedicated Vector Database](https://www.matthewswong.com/en/blog/pgvector-semantic-search-postgres): Build production semantic search inside PostgreSQL with pgvector: schema, HNSW vs IVFFlat, hybrid search SQL, and the honest limits of the approach. - [RAG vs Fine-Tuning: An Honest Decision Framework](https://www.matthewswong.com/en/blog/rag-vs-fine-tuning-decision): When to use RAG, when to fine-tune, and when neither: a decision table, four deciding questions, and the operational costs vendors do not quote. - [Building Production RAG Applications: Architecture & Evaluation](https://www.matthewswong.com/en/blog/building-production-rag-llm-applications): Build production-grade RAG systems with LangChain, pgvector, and RAGAS. Covers chunking strategies, MMR retrieval, hybrid search, and cost optimization. ## Blog — Security - [AI Agent Least Privilege: Credentials, Tokens and Secrets](https://www.matthewswong.com/en/blog/ai-agent-least-privilege-credentials): AI agent least privilege in practice: keep secrets out of context, use domain_secrets, per-request MCP tokens, scoped tool identities and approval gates. - [Red Teaming AI Agents With Promptfoo: A Practical Guide](https://www.matthewswong.com/en/blog/red-teaming-ai-agents-promptfoo): Red teaming AI agents with promptfoo: test indirect prompt injection through tool output, excessive agency and data leaks, then gate CI on the findings. - [PaaS Environment Secrets: Build-Time vs Runtime Injection](https://www.matthewswong.com/en/blog/paas-environment-secrets-management-teams): Managing PaaS environment secrets across three environments: what NEXT_PUBLIC_ bakes in forever, runtime injection, build-log leaks, and safe rotation. - [UU PDP Compliance Checklist for AI Features in Indonesia](https://www.matthewswong.com/en/blog/uu-pdp-ai-feature-compliance-checklist): A UU PDP compliance checklist for AI features in Indonesia: lawful basis, cross-border prompts, provider log retention, and what deletion must reach. - [AI Agent Identity: Delegated Authorization Beyond OAuth 2.1](https://www.matthewswong.com/en/blog/ai-agent-identity-delegated-authorization): Delegated authorization for AI agent identity: how the OAuth act claim, RFC 8693, Entra Agent ID and two IETF drafts answer who authorised an action. - [Claude Code Plugin Security: Audit Before You Install](https://www.matthewswong.com/en/blog/claude-code-plugin-supply-chain-security): A Claude Code plugin runs with your privileges. Here is the pre-install audit: hook commands, MCP egress, the skill prose, and pinning an exact commit. - [Claude Code Authentication: Every Login Method Explained](https://www.matthewswong.com/en/blog/claude-code-authentication-login-methods): Claude Code accepts seven kinds of credential and picks one by a fixed precedence order. Here is that order, where each is stored, and CI tokens. - [Claude Code Managed Settings: Policy That Actually Holds](https://www.matthewswong.com/en/blog/claude-code-managed-settings-enterprise-policy): Claude Code picks the first managed source with a policy key and ignores the rest — it does not merge them. Here is how to verify which one won. - [Claude Code Security Model: Layers, Trust and Limits](https://www.matthewswong.com/en/blog/claude-code-security-model-layers): Read-only defaults, an asymmetric directory boundary, and an accept-edits list that includes rm. Here is what actually gates a Claude Code session. - [Claude Code Zero Data Retention: What You Give Up](https://www.matthewswong.com/en/blog/claude-code-zero-data-retention-compliance): ZDR turns off five Claude Code features at the backend and one model class. Here is the exact list, the routing gap, and the retention exception. - [Claude Code Auto Mode: Tune the Permission Classifier](https://www.matthewswong.com/en/blog/claude-code-auto-mode-permission-classifier): Auto mode routes every tool call through a classifier. Here is how autoMode.environment, the four-tier precedence and classifyAllShell actually work. - [Claude Code Sandboxing: Run Bash Safely](https://www.matthewswong.com/en/blog/claude-code-sandboxing-bash-guide): Learn how Claude Code sandboxing runs bash safely: isolate the agent's filesystem and network, cut the lethal trifecta, and reduce prompt-injection risk. - [Sandboxing AI Agents and the Lethal Trifecta](https://www.matthewswong.com/en/blog/sandboxing-ai-agents-lethal-trifecta): Sandboxing AI coding agents confines the filesystem and network to break the lethal trifecta, so even a fully compromised agent stays safely contained. - [Claude Code Permission Modes: Autonomy vs Safety](https://www.matthewswong.com/en/blog/claude-code-permission-modes-guide): Learn Claude Code permission modes: how plan, default, acceptEdits, and bypassPermissions trade prompts for autonomy, and how to pick one per task. - [Prompt Injection Attacks on AI Coding Agents](https://www.matthewswong.com/en/blog/prompt-injection-ai-coding-agents): Prompt injection on AI coding agents hides commands in code, issues, and web pages. Learn why filtering fails and how containment reduces the risk. - [MCP Server Security Checklist for Developers](https://www.matthewswong.com/en/blog/mcp-server-security-checklist): A practical MCP server security checklist: validate token audience, block SSRF, secure sessions, harden stdio and HTTP transports, and stop tool poisoning. - [OAuth 2.1 vs OAuth 2.0: What Changed and How to Migrate](https://www.matthewswong.com/en/blog/oauth-2-1-vs-2-0-migration): OAuth 2.1 makes PKCE mandatory, drops the implicit and password grants, and bans bearer tokens in URLs. See what changed and how to migrate safely. - [Content Security Policy in Next.js: Nonces & strict-dynamic](https://www.matthewswong.com/en/blog/content-security-policy-nextjs-nonce): Add a strict Content Security Policy in Next.js with a per-request nonce and strict-dynamic in middleware, plus a safe Report-Only rollout guide. - [OpenFGA ReBAC: Fine-Grained Multi-Tenant Authorization](https://www.matthewswong.com/en/blog/openfga-rebac-multi-tenant-authorization): How OpenFGA brings Google Zanzibar-style ReBAC to multi-tenant apps: relationship tuples, an authorization model, the Check API, and where RBAC breaks. - [Cloudflare Tunnel Zero Trust: Expose Self-Hosted Apps](https://www.matthewswong.com/en/blog/cloudflare-tunnel-zero-trust-homelab): Set up Cloudflare Tunnel with cloudflared to expose self-hosted homelab and VPS services with no open ports, plus Zero Trust access policies for authentication. - [eBPF Observability with Cilium Tetragon on Kubernetes](https://www.matthewswong.com/en/blog/ebpf-observability-cilium-tetragon): How eBPF hooks the Linux kernel without modules and how Cilium Tetragon delivers process, network, and file runtime security on Kubernetes. - [Fixing IDOR in a Multi-Branch ERP with Prisma branchId Scoping](https://www.matthewswong.com/en/blog/branchid-scoping-idor-multi-branch-erp): A real IDOR fix in a multi-branch NestJS and Prisma ERP: scope every query by branchId with findFirst, enforce it with a guard, and test cross-branch access. - [NIK Dukcapil e-KYC: Verify Indonesian KTP Identity](https://www.matthewswong.com/en/blog/nik-ktp-dukcapil-verification-api-indonesia): How to build e-KYC for Indonesian fintech: verify NIK against Dukcapil via authorized providers, add face-match and liveness, and stay UU PDP compliant. - [systemd Service Hardening: Sandbox Linux Daemons Safely](https://www.matthewswong.com/en/blog/systemd-hardening-sandboxing-services): Harden Linux services with systemd sandboxing: ProtectSystem, PrivateTmp, NoNewPrivileges, SystemCallFilter, and systemd-analyze security scores. - [Encrypting Git Secrets with SOPS and age (Not Plaintext)](https://www.matthewswong.com/en/blog/sops-age-encrypted-secrets-git): Learn how to encrypt secrets in Git using SOPS and age: per-environment keys, CI decryption, and key rotation without plaintext .env file sprawl. - [Automated Secrets Rotation Strategy That Survives Audits](https://www.matthewswong.com/en/blog/automated-secrets-rotation-strategy): Design automated secrets rotation with short-lived credentials, dynamic secrets, and dual-secret cutovers for zero downtime and fast leak detection. - [Securing Software Supply Chains with SBOMs and Sigstore](https://www.matthewswong.com/en/blog/software-supply-chain-sbom-sigstore): Learn how to secure your software supply chain by generating SBOMs, signing artifacts with Sigstore and cosign, and verifying SLSA provenance in CI. - [Passkeys in Next.js: WebAuthn Passwordless Auth Guide](https://www.matthewswong.com/en/blog/passkeys-webauthn-nextjs-authentication): Add passkey authentication to Next.js with WebAuthn: registration, login flows, credential storage, security tips, and fallbacks for unsupported devices. - [Zero Trust Security Architecture for Cloud-Native Apps](https://www.matthewswong.com/en/blog/zero-trust-security-architecture-indonesia): Implement Zero Trust in Kubernetes with Istio mTLS, SPIFFE/SPIRE, and NetworkPolicy micro-segmentation. Includes BSSN compliance guidance for Indonesian organizations. - [UU PDP No. 27/2022: Developer Compliance Guide for Indonesia](https://www.matthewswong.com/en/blog/uu-pdp-compliance-developer-guide-indonesia): Translate UU PDP into engineering practice: pseudonymization, PostgreSQL RLS, 72-hour breach notification, data subject rights API, and cross-border transfer rules. ## Blog — Career & Indonesia Tech - [How to Organise a Developer Meetup in an Indonesian City](https://www.matthewswong.com/en/blog/indonesian-dev-community-meetup-organizing): The operational detail behind a developer meetup in an Indonesian city: getting a room, why RSVPs lie, WhatsApp reminders, talks, food and sponsors. - [Indonesia Tech Funding Winter 2026: An Engineer's Cost Playbook](https://www.matthewswong.com/en/blog/indonesia-tech-funding-winter-engineer-plan): Indonesia's 2026 tech funding winter reversed in two months. A playbook for engineers: which technical decisions get re-priced when capital is expensive. - [Bootcamp vs Self-Taught for Indonesian Developers in 2026](https://www.matthewswong.com/en/blog/indonesian-bootcamp-vs-self-taught-2026): Bootcamp vs self-taught for Indonesian developers in 2026: the real IDR course fees, what evidence each route produces, and what AI tooling changed. - [Indonesian Developer Discourse on X and Threads: 5 Arguments](https://www.matthewswong.com/en/blog/indonesian-developer-x-discourse-patterns): An honest read of the five arguments Indonesian developer discourse on X and Threads keeps replaying, and which ones rest on evidence you can check. - [AI Pair Programming and the Junior Developer Skill Gap](https://www.matthewswong.com/en/blog/ai-pair-programming-junior-skill-gap): AI pair programming erodes a junior developer's debugging loop, not their syntax. The five sub-skills at risk, plus a predict-first drill that keeps them. - [Growing an Engineering Blog with SEO: What Actually Worked](https://www.matthewswong.com/en/blog/engineering-blog-seo-growth-developer): How I grew a bilingual engineering blog using technical SEO: structured data, internal linking, and the long-tail keywords that moved real traffic. - [Building in Public as an Indonesian Developer: My Playbook](https://www.matthewswong.com/en/blog/building-in-public-indonesia-developer): Building in public as an Indonesian developer across WIB and global time zones brought real clients, feedback, and a portfolio audience I never expected. - [Balancing DevOps, ERP, and Web Dev as a Final-Year Engineering Student](https://www.matthewswong.com/en/blog/balancing-devops-erp-webdev-engineer): Honest reflections on juggling three technical domains simultaneously — the cognitive cost, the surprising synergies, and what I'd tell my past self. - [Code Review That Actually Works: A Developer's Process Guide](https://www.matthewswong.com/en/blog/code-review-process-developer): How to structure code reviews that catch real bugs, build team knowledge, and ship faster — including PR size limits, review checklists, and the metrics that tell you your process is working. - [Technical Debt Management: A Pragmatic Strategy for Development Teams](https://www.matthewswong.com/en/blog/technical-debt-management): McKinsey found technical debt accounts for 40% of IT balance sheets and causes teams to be 30% slower. Here's a practical framework for identifying, prioritizing, and systematically reducing technical debt without stalling feature work. - [Building a Documentation Culture: Why Engineers Don't Write Docs and How to Fix It](https://www.matthewswong.com/en/blog/developer-documentation-culture): Developers spend 3-10 hours per week searching for information that should be documented. Here's how to build a documentation culture that sticks — README-first, docs-as-code, and the structural fixes that actually work. - [Open Source Licenses Explained: MIT, Apache 2.0, and GPL for Developers](https://www.matthewswong.com/en/blog/open-source-license-guide): A practical guide to choosing between MIT, Apache 2.0, and GPL licenses for your open-source projects — with real-world implications for commercial use, patent protection, and copyleft requirements. - [Building a Portfolio as a Junior Developer: What Actually Gets You Hired](https://www.matthewswong.com/en/blog/portfolio-junior-developer-guide): A junior developer's honest guide to building a portfolio that gets callbacks — what interviewers actually look for vs what tutorial content tells you. - [Developer Productivity Tools I Actually Use in 2025](https://www.matthewswong.com/en/blog/developer-productivity-tools-2025): My real developer toolbox in 2025 — not what's trending, but what I reached for every day as a student, part-time DevOps engineer, and indie developer. - [Learning a New Tech Stack Efficiently: My Actual Process](https://www.matthewswong.com/en/blog/learning-new-tech-stack-efficiently): How to go from zero to productive in a new technology stack in 4-6 weeks — the learning sequence, resources, and practice strategies that actually work. - [How Open Source Contributions Boosted My Career (and How to Start)](https://www.matthewswong.com/en/blog/open-source-contribution-career): The real career impact of open source contributions — what kind of contributions matter for job hunting, and a practical guide to making your first meaningful PR. - [Tech Stack Used by Indonesian Companies in 2025: What the Market Actually Runs On](https://www.matthewswong.com/en/blog/tech-stack-indonesia): From GoTo's microservices to mid-sized ERP firms using NestJS — a realistic picture of what technologies Indonesian companies are actually deploying in 2025. - [Remote Work as an Indonesian Developer: Opportunities, Platforms, and What Nobody Tells You](https://www.matthewswong.com/en/blog/remote-work-indonesia): The real guide to landing and sustaining remote developer work from Indonesia — platforms, rate strategies, compliance, and the culture gaps that trip people up. - [Swiss German University IT Program Review: An Insider's Honest Assessment](https://www.matthewswong.com/en/blog/sgu-it-review): A recent SGU graduate's honest review of the IT program — what the curriculum actually covers, what it misses, and how it compares to self-taught paths in the Indonesian job market. - [Cloud Adoption in Indonesian Companies: The Real Picture in 2025](https://www.matthewswong.com/en/blog/cloud-adoption-indonesia): Indonesia's cloud market hit USD 2.46 billion in 2025 — but adoption patterns vary wildly by sector. Here's what's actually happening on the ground. - [ERP Market in Indonesia: Who's Using What and Why in 2025](https://www.matthewswong.com/en/blog/erp-market-indonesia): The Indonesian ERP market hit USD 1 billion in 2024 and is growing fast — here's a ground-level map of what companies are actually using, from SAP to Odoo to custom builds. - [Digital Transformation for SMEs in Indonesia: What Actually Works](https://www.matthewswong.com/en/blog/digital-transformation-sme): 63% of Indonesian SMEs use digital tools in 2025, but most digital transformation projects fail. Here's what works, what doesn't, and what developers can do about it. - [Indonesia Tech Startup Ecosystem in 2025: The Honest State of Play](https://www.matthewswong.com/en/blog/indonesia-tech-ecosystem): From 13 unicorns to a funding winter — the real state of Indonesia's tech startup ecosystem in 2025, and what it means for developers choosing where to work. - [Freelance Pricing as an Indonesian Developer: How to Set Your Rates Without Underselling](https://www.matthewswong.com/en/blog/freelance-pricing-indonesia): The complete guide to pricing freelance development work in Indonesia — domestic vs. international rates, project vs. hourly models, and how to stop competing on price. - [Work-Life Balance as a Developer: What Nobody Tells You Until You're Already Burned Out](https://www.matthewswong.com/en/blog/work-life-balance-dev): Honest reflections on maintaining work-life balance as a developer juggling a degree, part-time work, and side projects — with concrete strategies that actually work. - [Side Projects While Working Full-Time: A Real Strategy That Doesn't Destroy Your Life](https://www.matthewswong.com/en/blog/side-projects-full-time): How to maintain meaningful side projects alongside a full-time job (or degree) without burning out — with actual time management, scope discipline, and shipping strategies. - [Technical Interview Prep for Indonesian Developers: What's Actually Asked in 2025](https://www.matthewswong.com/en/blog/technical-interview-indonesia): A realistic guide to preparing for technical interviews at Indonesian tech companies — from startup screening calls to GoTo and Traveloka-style system design rounds. ## Blog — Product & SaaS - [Bilingual Technical SEO: hreflang for Indonesian and English](https://www.matthewswong.com/en/blog/bilingual-technical-seo-indonesian-english): Bilingual technical SEO in Next.js: per-locale canonical, reciprocal hreflang and x-default, plus why the Indonesian query is a different question. - [Threads vs X: Where Indonesian Developers Actually Read](https://www.matthewswong.com/en/blog/threads-vs-x-developer-audience-indonesia): Threads reports 400 million monthly active users. X publishes nothing comparable. How to measure which one actually sends readers to a technical blog. - [Cloud Billing in Indonesia: The Credit Card Wall and QRIS](https://www.matthewswong.com/en/blog/credit-card-wall-indonesian-developers-qris): Cloud billing in Indonesia runs on international credit cards that 1.6 percent of adults hold. What that gate blocks, and how QRIS billing clears it. - [Claude Code Team Rollout: An Adoption Playbook That Works](https://www.matthewswong.com/en/blog/claude-code-team-rollout-adoption-playbook): Rolling Claude Code out to a team is a configuration problem, not a training one. Here is what to ship, what to enforce, and what to measure. - [Claude Code in Slack: Setup, Claude Tag, and Real Limits](https://www.matthewswong.com/en/blog/claude-code-slack-integration-claude-tag): Claude Code in Slack routes an at-Claude mention to a cloud session. Here is the setup order that works, how Claude Tag differs, and the real limits. - [Thermal Receipt Design Principles for Epson TM-T82](https://www.matthewswong.com/en/blog/epson-tm-t82-receipt-design-principles): Receipt design for thermal printers: why bold is contrast control, the four-level hierarchy, column budgets, and what still reads after fading. - [Building a POS + Mobile ERP for an Indonesian Carwash SME](https://www.matthewswong.com/en/blog/building-pos-mobile-indonesian-sme-carwash): How I built a POS and mobile ERP for an Indonesian carwash SME: a NestJS API, Next.js POS, and offline Flutter field app handling cash and kasbon. - [SaaS Distribution on LinkedIn and Threads in Indonesia](https://www.matthewswong.com/en/blog/saas-distribution-linkedin-threads-indonesia): SaaS distribution in Indonesia now runs on LinkedIn and Threads, not paid ads. A build-in-public playbook to win your first 100 bootstrapped customers. - [Warung Inventory Micro-SaaS: Offline-First for Indonesia](https://www.matthewswong.com/en/blog/warung-inventory-micro-saas-indonesia): How to build a warung inventory micro-SaaS: offline-first stok barang tracking for Indonesian shops, cheap infra, and WhatsApp low-stock alerts. - [Vertical SaaS for Indonesian Clinics and Salons](https://www.matthewswong.com/en/blog/vertical-saas-klinik-salon-indonesia): Why vertical SaaS in Indonesia is a strong 2026 bet, and how to build a booking and CRM app for underserved service SMEs like clinics and salons. - [Micro-SaaS Pricing for Indonesia: IDR Pricing That Converts](https://www.matthewswong.com/en/blog/micro-saas-pricing-indonesia-idr): Micro-SaaS pricing in Indonesia needs IDR tiers, a low decision threshold, and QRIS billing. Learn per-outlet models, prepay discounts, and pricing traps. - [Building My First SaaS: AI Gym Bro](https://www.matthewswong.com/en/blog/building-saas-ai-gymbro): How I built AI Gym Bro, an AI-powered fitness companion SaaS — from idea to launch with Next.js, Groq, and a lot of iteration. Lessons on product, AI, and shipping fast. ## Blog — University - [My Experience at Swiss German University](https://www.matthewswong.com/en/blog/life-at-swiss-german-university): My honest experience studying Information Technology at Swiss German University — campus life, curriculum, industry exposure, and what I'd tell my younger self. ## Blog — Hackathons - [Competing in PwC Capture The Flag](https://www.matthewswong.com/en/blog/pwc-capture-the-flag): What it's like competing in PwC's Capture The Flag competition — the challenges I tackled, what I learned about cybersecurity, and how CTFs sharpen real-world security instincts. ## Languages This site is available in English (`/en/`) and Indonesian (`/id/`). Each article is fully translated.