Skip to main content
Dev ToolsBlog
HomeArticlesCategories

Dev Tools Blog

Modern development insights and cutting-edge tools for today's developers.

Quick Links

  • ArticlesView all development articles
  • CategoriesBrowse articles by category

Technologies

Built with Next.js 15, React 19, TypeScript, and Tailwind CSS.

© 2025 Dev Tools Blog. All rights reserved.

← Back to Home
Developer Tools

Developer Utilities & Best Practices: Essential Tools for Modern Web Development

Master essential developer utilities including CLI automation, Git workflows, Docker, code quality tools, debugging techniques, and CI/CD pipelines for 2025.

Published: 9/18/2025

Developer Utilities & Best Practices: Essential Tools for Modern Web Development

Modern web development is a complex ecosystem where efficiency, code quality, and continuous learning separate good developers from great ones. This comprehensive guide covers essential developer utilities, debugging tools, and best practices that can dramatically improve your development workflow and career trajectory in 2025.

Executive Summary

Successful modern web development relies on mastering the right combination of tools, practices, and workflows. The developers who thrive are those who invest in learning efficient debugging techniques, adopt proven development practices, and continuously optimize their development environment. With advanced CLI tools, automated workflows, and sophisticated monitoring systems, today's developers can achieve unprecedented levels of productivity and code quality.

Advanced CLI Tools and Automation

Modern CLI Development with Bun and Deno

// Advanced CLI tool with Bun
import { Command } from 'commander'
import chalk from 'chalk'
import ora from 'ora'
import inquirer from 'inquirer'

interface ProjectConfig { name: string framework: 'next' | 'remix' | 'astro' | 'vite' features: string[] }

const program = new Command()

program .name('create-modern-app') .description('CLI to bootstrap modern web applications') .version('1.0.0')

program .command('init') .description('Initialize a new project') .action(async () => { const answers = await inquirer.prompt([ { type: 'input', name: 'name', message: 'Project name:', default: 'my-app' }, { type: 'list', name: 'framework', message: 'Choose a framework:', choices: ['next', 'remix', 'astro', 'vite'] }, { type: 'checkbox', name: 'features', message: 'Select features:', choices: [ 'TypeScript', 'Tailwind CSS', 'ESLint', 'Prettier', 'Vitest', 'Playwright' ] } ])

await createProject(answers) })

async function createProject(config: ProjectConfig) { const spinner = ora('Creating project...').start()

try { // Create project directory await Bun.spawn(['mkdir', '-p', config.name]).exited

// Initialize package.json const packageJson = { name: config.name, version: '1.0.0', type: 'module', scripts: { dev: 'vite', build: 'vite build', preview: 'vite preview', test: 'vitest', lint: 'eslint .' }, dependencies: {}, devDependencies: {} }

await Bun.write( ${config.name}/package.json, JSON.stringify(packageJson, null, 2) )

// Install dependencies spinner.text = 'Installing dependencies...' await Bun.spawn(['bun', 'install'], { cwd: config.name }).exited

spinner.succeed(chalk.green('Project created successfully!'))

console.log(chalk.cyan('\nNext steps:')) console.log(chalk.gray( cd ${config.name})) console.log(chalk.gray(' bun run dev')) } catch (error) { spinner.fail(chalk.red('Failed to create project')) console.error(error) } }

program.parse()

Git Workflow Automation

#!/bin/bash

Advanced Git workflow automation script

git-workflow.sh - Intelligent commit and push workflow

set -e

Colors

RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m'

Check if we're in a git repository

if ! git rev-parse --git-dir > /dev/null 2>&1; then echo -e "${RED}Error: Not a git repository${NC}" exit 1 fi

Get branch name

BRANCH=$(git branch --show-current)

Check for uncommitted changes

if [[ -z $(git status -s) ]]; then echo -e "${YELLOW}No changes to commit${NC}" exit 0 fi

Run pre-commit checks

echo -e "${GREEN}Running pre-commit checks...${NC}"

TypeScript type checking

if [ -f "tsconfig.json" ]; then echo "Running TypeScript checks..." npx tsc --noEmit fi

ESLint

if [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ]; then echo "Running ESLint..." npx eslint . --max-warnings 0 fi

Prettier

if [ -f ".prettierrc" ]; then echo "Running Prettier..." npx prettier --check . fi

Run tests

if [ -f "vitest.config.ts" ]; then echo "Running tests..." npx vitest run fi

Stage all changes

git add -A

Generate commit message using AI

echo -e "${GREEN}Generating commit message...${NC}" DIFF=$(git diff --staged) COMMIT_MSG=$(echo "$DIFF" | npx ai-commit-message)

Confirm commit

echo -e "\n${YELLOW}Proposed commit message:${NC}" echo "$COMMIT_MSG" read -p "Proceed with commit? (y/n) " -n 1 -r echo

if [[ $REPLY =~ ^[Yy]$ ]]; then git commit -m "$COMMIT_MSG"

# Push to remote read -p "Push to remote? (y/n) " -n 1 -r echo

if [[ $REPLY =~ ^[Yy]$ ]]; then git push origin "$BRANCH" echo -e "${GREEN}Changes pushed successfully!${NC}" fi else git reset HEAD echo -e "${RED}Commit cancelled${NC}" fi

Custom Git Hooks

#!/bin/bash

.git/hooks/pre-commit - Advanced pre-commit validation

Prevent commits to main/master

BRANCH=$(git branch --show-current) if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then echo "🚫 Direct commits to $BRANCH are not allowed!" echo "Please create a feature branch:" echo " git checkout -b feature/your-feature-name" exit 1 fi

Check for console.log statements

if git diff --cached --name-only | grep -E '\.(ts|tsx|js|jsx)$' | xargs grep -n "console\.log" > /dev/null; then echo "⚠️ Found console.log statements in staged files:" git diff --cached --name-only | grep -E '\.(ts|tsx|js|jsx)$' | xargs grep -n "console\.log" echo "" read -p "Proceed anyway? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi

Check for TODO comments

if git diff --cached | grep -i "TODO\|FIXME" > /dev/null; then echo "📝 Found TODO/FIXME comments in changes" git diff --cached | grep -i "TODO\|FIXME" echo "" fi

Run linters

echo "🔍 Running linters..." npx lint-staged

exit 0

Docker and Containerization

Advanced Docker Compose Setup

docker-compose.yml - Production-ready multi-service setup

version: '3.9'

services: app: build: context: . dockerfile: Dockerfile target: production ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=postgresql://user:password@db:5432/myapp - REDIS_URL=redis://redis:6379 depends_on: db: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped

db: image: postgres:16-alpine ports: - "5432:5432" environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=password - POSTGRES_DB=myapp volumes: - postgres_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U user"] interval: 10s timeout: 5s retries: 5

redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 command: redis-server --appendonly yes

nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./certs:/etc/nginx/certs depends_on: - app

volumes: postgres_data: redis_data:

Multi-Stage Docker Build

Dockerfile - Optimized multi-stage build

FROM node:20-alpine AS base WORKDIR /app RUN corepack enable && corepack prepare pnpm@latest --activate

FROM base AS deps COPY package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile

FROM base AS builder COPY --from=deps /app/node_modules ./node_modules COPY . . RUN pnpm run build

FROM base AS runner ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000 ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

Code Quality and Linting

Advanced ESLint Configuration

// eslint.config.js - ESLint Flat Config (2025)
import js from '@eslint/js'
import typescript from '@typescript-eslint/eslint-plugin'
import typescriptParser from '@typescript-eslint/parser'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import prettier from 'eslint-config-prettier'

export default [ js.configs.recommended, { files: ['**/*.{ts,tsx}'], languageOptions: { parser: typescriptParser, parserOptions: { ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { jsx: true }, project: './tsconfig.json' } }, plugins: { '@typescript-eslint': typescript, 'react': react, 'react-hooks': reactHooks }, rules: { ...typescript.configs['recommended'].rules, ...react.configs['recommended'].rules, ...reactHooks.configs['recommended'].rules,

// TypeScript specific '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-non-null-assertion': 'warn',

// React specific 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn',

// General 'no-console': ['warn', { allow: ['warn', 'error'] }], 'prefer-const': 'error', 'no-var': 'error' } }, prettier ]

Automated Code Formatting

// .prettierrc.json
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "avoid",
  "endOfLine": "lf",
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-organize-imports"
  ],
  "tailwindConfig": "./tailwind.config.ts",
  "tailwindFunctions": ["clsx", "cn", "cva"]
}

Environment Management

Advanced Environment Configuration

// env.config.ts - Type-safe environment variables
import { z } from 'zod'

const envSchema = z.object({ // App NODE_ENV: z.enum(['development', 'production', 'test']), APP_URL: z.string().url(), PORT: z.coerce.number().default(3000),

// Database DATABASE_URL: z.string().url(), DATABASE_POOL_MIN: z.coerce.number().default(2), DATABASE_POOL_MAX: z.coerce.number().default(10),

// Redis REDIS_URL: z.string().url(), REDIS_TTL: z.coerce.number().default(3600),

// Auth JWT_SECRET: z.string().min(32), JWT_EXPIRES_IN: z.string().default('7d'),

// External APIs OPENAI_API_KEY: z.string().startsWith('sk-'), STRIPE_SECRET_KEY: z.string().startsWith('sk_'), STRIPE_WEBHOOK_SECRET: z.string().startsWith('whsec_'),

// Monitoring SENTRY_DSN: z.string().url().optional(), DATADOG_API_KEY: z.string().optional() })

export type Env = z.infer

function validateEnv(): Env { const parsed = envSchema.safeParse(process.env)

if (!parsed.success) { console.error('❌ Invalid environment variables:') console.error(JSON.stringify(parsed.error.format(), null, 2)) process.exit(1) }

return parsed.data }

export const env = validateEnv()

// Usage import { env } from './env.config' console.log(env.DATABASE_URL) // Type-safe!

Multiple Environment Management

// .env.development
NODE_ENV=development
APP_URL=http://localhost:3000
DATABASE_URL=postgresql://user:password@localhost:5432/myapp_dev
REDIS_URL=redis://localhost:6379

// .env.staging NODE_ENV=production APP_URL=https://staging.myapp.com DATABASE_URL=postgresql://user:password@staging-db.internal:5432/myapp_staging REDIS_URL=redis://staging-redis.internal:6379

// .env.production NODE_ENV=production APP_URL=https://myapp.com DATABASE_URL=postgresql://user:password@prod-db.internal:5432/myapp_prod REDIS_URL=redis://prod-redis.internal:6379

Advanced Debugging Tools

Browser DevTools Mastery

// Advanced debugging techniques
class DebugUtils {
  // Performance profiling
  static profile(name: string, fn: () => void) {
    console.profile(name)
    performance.mark(${name}-start)

fn()

performance.mark(${name}-end) performance.measure(name, ${name}-start, ${name}-end) console.profileEnd(name)

const measure = performance.getEntriesByName(name)[0] console.log(${name}: ${measure.duration.toFixed(2)}ms) }

// Memory leak detection static trackMemory(interval = 5000) { setInterval(() => { if (performance.memory) { const { usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit } = performance.memory

console.table({ 'Used Heap': ${(usedJSHeapSize / 1048576).toFixed(2)} MB, 'Total Heap': ${(totalJSHeapSize / 1048576).toFixed(2)} MB, 'Heap Limit': ${(jsHeapSizeLimit / 1048576).toFixed(2)} MB, 'Usage': ${((usedJSHeapSize / jsHeapSizeLimit) * 100).toFixed(2)}% }) } }, interval) }

// Network debugging static interceptFetch() { const originalFetch = window.fetch

window.fetch = async (...args) => { const [url, options] = args

console.group(🌐 Fetch: ${url}) console.log('Options:', options)

const startTime = performance.now()

try { const response = await originalFetch(...args) const endTime = performance.now()

console.log(Status: ${response.status}) console.log(Duration: ${(endTime - startTime).toFixed(2)}ms) console.groupEnd()

return response } catch (error) { console.error('Error:', error) console.groupEnd() throw error } } }

// React component debugging static whyDidYouRender(component: React.ComponentType) { if (process.env.NODE_ENV === 'development') { ;(component as any).whyDidYouRender = true } } }

// Usage DebugUtils.profile('expensive-operation', () => { // Your code here })

DebugUtils.trackMemory() DebugUtils.interceptFetch()

VS Code Configuration

// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "explicit"
  },
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.updateImportsOnFileMove.enabled": "always",
  "files.associations": {
    "*.css": "tailwindcss"
  },
  "tailwindCSS.experimental.classRegex": [
    ["cva\\(([^)]*)\\)", "[\"']([^\"']*).*?[\"']"],
    ["cn\\(([^)]*)\\)", "[\"']([^\"']*).*?[\"']"]
  ],
  "emmet.includeLanguages": {
    "javascript": "javascriptreact",
    "typescript": "typescriptreact"
  }
}

Launch Configurations

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}"
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev",
      "serverReadyAction": {
        "pattern": "started server on .+, url: (https?://.+)",
        "uriFormat": "%s",
        "action": "debugWithChrome"
      }
    }
  ]
}

Performance Monitoring and Profiling

Application Performance Monitoring

// performance-monitor.ts - Comprehensive APM
import { trace, context, SpanStatusCode } from '@opentelemetry/api'
import { NodeSDK } from '@opentelemetry/sdk-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'

class PerformanceMonitor { private sdk: NodeSDK

constructor() { const traceExporter = new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT })

this.sdk = new NodeSDK({ traceExporter, instrumentations: [] })

this.sdk.start() }

async measureAsync(name: string, fn: () => Promise): Promise { const tracer = trace.getTracer('app')

return tracer.startActiveSpan(name, async (span) => { try { const result = await fn() span.setStatus({ code: SpanStatusCode.OK }) return result } catch (error) { span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }) throw error } finally { span.end() } }) }

trackWebVitals() { if (typeof window === 'undefined') return

import('web-vitals').then(({ onCLS, onFID, onFCP, onLCP, onTTFB }) => { onCLS(metric => this.sendToAnalytics('CLS', metric)) onFID(metric => this.sendToAnalytics('FID', metric)) onFCP(metric => this.sendToAnalytics('FCP', metric)) onLCP(metric => this.sendToAnalytics('LCP', metric)) onTTFB(metric => this.sendToAnalytics('TTFB', metric)) }) }

private sendToAnalytics(metricName: string, metric: any) { fetch('/api/analytics', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: metricName, value: metric.value, id: metric.id, rating: metric.rating }) }) } }

export const performanceMonitor = new PerformanceMonitor()

Error Tracking and Monitoring

// error-tracking.ts - Sentry integration
import * as Sentry from '@sentry/nextjs'

Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV, tracesSampleRate: 1.0,

beforeSend(event, hint) { // Filter out sensitive data if (event.request?.headers) { delete event.request.headers['authorization'] delete event.request.headers['cookie'] }

// Add custom context event.contexts = { ...event.contexts, app: { version: process.env.APP_VERSION, build: process.env.BUILD_ID } }

return event },

integrations: [ new Sentry.BrowserTracing(), new Sentry.Replay({ maskAllText: true, blockAllMedia: true }) ] })

// Custom error boundary export class ErrorBoundary extends React.Component { componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { Sentry.captureException(error, { contexts: { react: { componentStack: errorInfo.componentStack } } }) }

render() { return this.props.children } }

Documentation Generation

Automated API Documentation

// generate-docs.ts - Automatic API docs
import { generateSchema } from 'ts-json-schema-generator'
import * as fs from 'fs'

function generateAPIDocs() { const schema = generateSchema(tsconfig, 'src/types/api.ts', 'APISchema')

const markdown =

API Documentation

Endpoints

${Object.entries(schema.definitions).map(([name, def]) =>

${name}

\\\typescript ${JSON.stringify(def, null, 2)} \\\ ).join('\n')}

fs.writeFileSync('docs/api.md', markdown) }

Testing Infrastructure

Vitest Configuration

// vitest.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import path from 'path'

export default defineConfig({ plugins: [react()], test: { globals: true, environment: 'jsdom', setupFiles: ['./test/setup.ts'], coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], exclude: [ 'node_modules/', 'test/', '**/*.d.ts', '**/*.config.*', '**/mockData/', '**/.{idea,git,cache,output,temp}/' ] }, mockReset: true, restoreMocks: true }, resolve: { alias: { '@': path.resolve(__dirname, './src') } } })

E2E Testing with Playwright

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test'

export default defineConfig({ testDir: './e2e', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: [ ['html'], ['json', { outputFile: 'test-results/results.json' }] ], use: { baseURL: 'http://localhost:3000', trace: 'on-first-retry', screenshot: 'only-on-failure' }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } }, { name: 'Mobile Safari', use: { ...devices['iPhone 12'] } } ], webServer: { command: 'npm run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI } })

CI/CD Pipeline

GitHub Actions Workflow

.github/workflows/ci.yml

name: CI/CD Pipeline

on: push: branches: [main, develop] pull_request: branches: [main]

jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bun install - run: bun run lint - run: bun run type-check

test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bun install - run: bun run test:coverage - uses: codecov/codecov-action@v3 with: files: ./coverage/coverage-final.json

e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bun install - run: bunx playwright install --with-deps - run: bun run test:e2e - uses: actions/upload-artifact@v4 if: always() with: name: playwright-report path: playwright-report/

build: runs-on: ubuntu-latest needs: [lint, test] steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 - run: bun install - run: bun run build - uses: actions/upload-artifact@v4 with: name: build path: .next/

deploy: runs-on: ubuntu-latest needs: [build, e2e] if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: name: build path: .next/ - uses: amondnet/vercel-action@v25 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} vercel-args: '--prod'

Conclusion

Developer utilities and best practices are not just nice-to-have additions—they're essential infrastructure for professional development work. By mastering these tools and techniques, developers can build applications that are maintainable, performant, and reliable.

Key takeaways for modern development workflows in 2025:

  • 1. CLI Automation: Build custom tools to automate repetitive tasksCLI Automation: Build custom tools to automate repetitive tasks
  • 2. Git Workflows: Implement hooks and automation for code qualityGit Workflows: Implement hooks and automation for code quality
  • 3. Docker Mastery: Multi-stage builds and orchestration for all environmentsDocker Mastery: Multi-stage builds and orchestration for all environments
  • 4. Code Quality: ESLint, Prettier, and automated formattingCode Quality: ESLint, Prettier, and automated formatting
  • 5. Environment Management: Type-safe configuration with Zod validationEnvironment Management: Type-safe configuration with Zod validation
  • 6. Advanced Debugging: Master browser DevTools and VS Code featuresAdvanced Debugging: Master browser DevTools and VS Code features
  • 7. Performance Monitoring: Track Web Vitals and application metricsPerformance Monitoring: Track Web Vitals and application metrics
  • 8. Error Tracking: Comprehensive error monitoring with SentryError Tracking: Comprehensive error monitoring with Sentry
  • 9. Testing Infrastructure: Unit, integration, and E2E test coverageTesting Infrastructure: Unit, integration, and E2E test coverage
  • 10. CI/CD Excellence: Automated pipelines for quality and deploymentCI/CD Excellence: Automated pipelines for quality and deployment

The modern developer's toolkit is vast and powerful. By investing time in learning these tools and establishing robust workflows, you can achieve unprecedented levels of productivity, code quality, and professional growth. The future of web development belongs to those who master not just the code, but the entire development ecosystem.

Key Features

  • ▸Advanced CLI Tools

    Custom automation with Bun and Deno

  • ▸Git Workflow Automation

    Pre-commit hooks and intelligent workflows

  • ▸Docker Multi-Stage Builds

    Optimized containerization strategies

  • ▸ESLint Flat Config

    Modern linting with 2025 configuration

  • ▸Type-Safe Environment

    Zod-validated environment variables

  • ▸Advanced Debugging

    Browser DevTools and VS Code mastery

  • ▸Performance Monitoring

    OpenTelemetry and Web Vitals tracking

  • ▸Error Tracking

    Sentry integration and error boundaries

  • ▸Testing Infrastructure

    Vitest and Playwright configuration

  • ▸CI/CD Excellence

    GitHub Actions automated pipelines

Related Links

  • Bun Runtime ↗
  • Docker Documentation ↗
  • ESLint ↗
  • Playwright ↗