Developer Experience (DX): Internal Tooling, Golden Paths, and Platform Engineering
Build internal developer platforms that improve DX — self-service infrastructure, golden paths, developer portals, and platform engineering practices that reduc
Developer Experience (DX): Internal Tooling, Golden Paths, and Platform Engineering
Developer experience is how it feels to build software at your company. Good DX means engineers spend their time solving the product problem, not fighting infrastructure. Bad DX means every new service requires reading 4 wiki pages and asking 3 different people before the first line of product code is written.
At 10 engineers, DX problems are friction. At 100, they're the difference between shipping and not shipping.
Measuring DX: DORA Metrics
The DORA (DevOps Research and Assessment) metrics are the industry standard for measuring engineering productivity:
| Metric | Elite | High | Medium | Low |
|---|---|---|---|---|
| Deployment frequency | Multiple/day | Weekly | Monthly | Quarterly |
| Lead time for changes | < 1 hour | 1 day–1 week | 1–6 months | > 6 months |
| Change failure rate | < 5% | 5–15% | 15–45% | > 45% |
| MTTR (recovery time) | < 1 hour | < 1 day | < 1 week | > 1 month |
Elite performers (Google, Netflix, Amazon) deploy multiple times per day with a change failure rate under 5%. They achieve this through DX investment — not heroics.
The key insight: high deployment frequency and high stability aren't in tension. Teams that deploy more often have smaller, lower-risk changes and better tooling to detect and recover from failures.
Golden Paths: Opinionated Defaults
A golden path is the supported, recommended way to do something. It trades flexibility for speed: engineers following the golden path don't need to make infrastructure decisions — the decisions are already made.
Example: New service golden path
# Without golden path — what most teams do
# Engineer spends 2–3 days:
# 1. Copies an old service's Dockerfile
# 2. Sets up CI from scratch (usually copies an old workflow)
# 3. Figures out how to add it to the load balancer
# 4. Creates secrets manually in AWS Secrets Manager
# 5. Sets up monitoring (or forgets to)
# 6. Creates the service's own ECR repository
# With golden path — what good platform teams build
npx create-service my-new-service --template=fastify-api
# This generates:
# ✅ Service scaffold (Fastify + TypeScript + Prisma)
# ✅ Dockerfile optimized for the company's base image
# ✅ GitHub Actions CI/CD workflow
# ✅ Terraform module for ECS service + ALB + security groups
# ✅ Datadog/CloudWatch monitoring configured
# ✅ Secrets Manager paths pre-defined
# ✅ Service catalog entry created
# Time: 30 minutes instead of 2–3 days
Building a service generator with Plop.js:
// plopfile.ts
import { NodePlopAPI } from 'plop';
export default function (plop: NodePlopAPI) {
plop.setGenerator('service', {
description: 'Create a new backend service',
prompts: [
{
type: 'input',
name: 'name',
message: 'Service name (kebab-case):',
validate: (v) => /^[a-z][a-z0-9-]*$/.test(v) || 'Must be kebab-case',
},
{
type: 'list',
name: 'template',
message: 'Template:',
choices: ['fastify-api', 'worker', 'cron-job', 'grpc-service'],
},
{
type: 'list',
name: 'database',
message: 'Database:',
choices: ['postgres', 'none'],
},
],
actions: [
{
type: 'addMany',
destination: 'services/{{name}}',
base: 'templates/{{template}}',
templateFiles: 'templates/{{template}}/**/*',
globOptions: { dot: true },
},
{
type: 'add',
path: 'services/{{name}}/terraform/main.tf',
templateFile: 'templates/terraform/service.tf.hbs',
},
{
type: 'add',
path: '.github/workflows/{{name}}.yml',
templateFile: 'templates/ci/service.yml.hbs',
},
],
});
}
🌐 Looking for a Dev Team That Actually Delivers?
Most agencies sell you a project manager and assign juniors. Viprasol is different — senior engineers only, direct Slack access, and a 5.0★ Upwork record across 100+ projects.
- React, Next.js, Node.js, TypeScript — production-grade stack
- Fixed-price contracts — no surprise invoices
- Full source code ownership from day one
- 90-day post-launch support included
Self-Service Infrastructure
The biggest DX bottleneck in most companies: engineers need an ops team member to provision infrastructure. Self-service infrastructure removes this bottleneck.
Terraform modules as the self-service primitive:
# modules/ecs-service/main.tf — shared module engineers use
# Usage: engineers don't write Terraform from scratch, they use modules
variable "service_name" { type = string }
variable "image_tag" { type = string }
variable "cpu" { type = number; default = 256 }
variable "memory" { type = number; default = 512 }
variable "min_count" { type = number; default = 1 }
variable "max_count" { type = number; default = 10 }
variable "port" { type = number; default = 3000 }
variable "environment_variables" {
type = map(string)
default = {}
}
resource "aws_ecs_task_definition" "service" {
family = var.service_name
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.cpu
memory = var.memory
execution_role_arn = data.aws_iam_role.ecs_execution.arn
task_role_arn = aws_iam_role.service_task.arn
container_definitions = jsonencode([{
name = var.service_name
image = "${data.aws_ecr_repository.service.repository_url}:${var.image_tag}"
portMappings = [{ containerPort = var.port, protocol = "tcp" }]
environment = [for k, v in var.environment_variables : { name = k, value = v }]
secrets = [
{
name = "DATABASE_URL"
valueFrom = "arn:aws:secretsmanager:us-east-1:${data.aws_caller_identity.current.account_id}:secret:${var.service_name}/database-url"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = "/ecs/${var.service_name}"
"awslogs-region" = "us-east-1"
"awslogs-stream-prefix" = "ecs"
}
}
healthCheck = {
command = ["CMD-SHELL", "curl -f http://localhost:${var.port}/health || exit 1"]
interval = 30
timeout = 5
retries = 3
startPeriod = 60
}
}])
}
# Engineers use this module in their service's Terraform:
# module "my_service" {
# source = "../../modules/ecs-service"
# service_name = "my-service"
# image_tag = var.image_tag
# cpu = 512
# memory = 1024
# }
Developer Portal
At 50+ engineers, a developer portal becomes the central hub for DX: service catalog, documentation, API reference, runbooks, and self-service actions in one place.
Backstage (by Spotify) — the open-source developer portal:
# catalog-info.yaml — every service registers itself
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
title: Payment Service
description: Handles payment processing, refunds, and Stripe integration
annotations:
github.com/project-slug: myorg/payment-service
backstage.io/techdocs-ref: dir:.
datadoghq.com/site: us5.datadoghq.com
pagerduty.com/service-id: P1234567
tags:
- payments
- stripe
- backend
links:
- url: https://grafana.internal/d/payment-service
title: Grafana Dashboard
- url: https://runbooks.internal/payment-service
title: Runbooks
spec:
type: service
lifecycle: production
owner: team-payments
system: payment-platform
dependsOn:
- component:user-service
- component:notification-service
providesApis:
- payment-api-v2
What Backstage provides out-of-the-box:
- Service catalog — every service, its owner, and its dependencies
- TechDocs — auto-rendered documentation from markdown in repos
- Software templates — the golden path generators
- Plugin ecosystem — CI/CD status, incident history, API explorer
- Search across all of the above
🚀 Senior Engineers. No Junior Handoffs. Ever.
You get the senior developer, not a project manager who relays your requirements to someone you never meet. Every Viprasol project has a senior lead from kickoff to launch.
- MVPs in 4–8 weeks, full platforms in 3–5 months
- Lighthouse 90+ performance scores standard
- Works across US, UK, AU timezones
- Free 30-min architecture review, no commitment
Local Development Experience
The local development environment is where engineers spend the most time. Friction here compounds every day.
docker-compose.yml for local dependencies:
# docker-compose.yml — run all dependencies with one command
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: myapp_dev
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
ports: ["5432:5432"]
volumes: [postgres-data:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dev -d myapp_dev"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports: ["6379:6379"]
command: redis-server --appendonly yes
volumes: [redis-data:/data]
localstack:
image: localstack/localstack:latest
environment:
SERVICES: s3,sqs,secretsmanager
DEFAULT_REGION: us-east-1
ports: ["4566:4566"]
volumes: ["/var/run/docker.sock:/var/run/docker.sock"]
volumes:
postgres-data:
redis-data:
Makefile for common tasks (reduces "how do I run X?" questions):
# Makefile
.PHONY: setup dev test lint db-migrate db-seed
setup:
cp .env.example .env
npm install
docker compose up -d
npm run db:migrate
npm run db:seed
@echo "✅ Development environment ready. Run 'make dev' to start."
dev:
docker compose up -d
npm run dev
test:
docker compose up -d postgres redis
npm test
lint:
npm run lint
npm run type-check
db-migrate:
npm run db:migrate
db-seed:
npm run db:seed
db-reset:
npm run db:reset
npm run db:seed
logs:
docker compose logs -f
One command to set up, one command to start — new engineers are productive on day one.
Measuring DX Investment ROI
DX investment is hard to justify with a spreadsheet, but these proxies help:
| Metric | Before | After | Impact |
|---|---|---|---|
| New service setup time | 2–3 days | 30 minutes | ~160 hours saved per service |
| Onboarding time to first PR | 3–5 days | 1 day | 2–4 days per new hire |
| CI pipeline duration | 45 minutes | 8 minutes | ~37 min × N runs/day |
| "How do I..." questions in Slack | 20–30/week | 5–8/week | Estimated 10h/week senior eng time |
At $150/hr for senior engineers, reducing 10 hours of "how do I..." questions per week is worth $78,000/year.
Working With Viprasol
We build internal developer platforms for product companies scaling their engineering teams — service templates, self-service Terraform modules, Backstage setups, and local development environments that get engineers productive in hours instead of days.
→ Talk to our platform engineering team about improving your DX.
See Also
- DevOps Best Practices — the CI/CD foundation for good DX
- Infrastructure as Code — Terraform modules for self-service infra
- Monorepo Tools — repository structure and tooling
- Hiring Software Engineers — DX as a talent retention factor
- Cloud Solutions — platform engineering and infrastructure
About the Author
Viprasol Tech Team
Custom Software Development Specialists
The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.
Need a Modern Web Application?
From landing pages to complex SaaS platforms — we build it all with Next.js and React.
Free consultation • No commitment • Response within 24 hours
Need a custom web application built?
We build React and Next.js web applications with Lighthouse ≥90 scores, mobile-first design, and full source code ownership. Senior engineers only — from architecture through deployment.