Skip to content

Development

amazingkj edited this page Jan 21, 2026 · 1 revision

Development

Project Structure

stale/
├── cmd/server/         # Application entrypoint
├── internal/
│   ├── api/            # HTTP handlers and middleware
│   │   ├── handler/    # Request handlers
│   │   └── middleware/ # Auth, CORS, rate limiting, etc.
│   ├── domain/         # Domain models
│   ├── repository/     # Database layer (SQLite)
│   └── service/        # Business logic
│       ├── cache/      # In-memory caching
│       ├── github/     # GitHub API client
│       ├── gitlab/     # GitLab API client
│       ├── npm/        # npm registry client
│       ├── maven/      # Maven Central client
│       ├── golang/     # pkg.go.dev client
│       ├── scanner/    # Repository scanner
│       └── scheduler/  # Cron scheduler
└── ui/                 # React frontend (Vite + TypeScript)
    ├── src/
    │   ├── api/        # API client
    │   ├── components/ # Reusable UI components
    │   ├── pages/      # Page components
    │   ├── constants/  # Shared styles and constants
    │   └── types/      # TypeScript types
    └── public/         # Static assets

Prerequisites

  • Go 1.21+
  • Node.js 18+
  • pnpm

Backend Development

# Run server with hot reload (use air or similar)
go run ./cmd/server

# Run tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Build binary
go build -o stale ./cmd/server

Key Packages

Package Description
chi HTTP router
sqlx SQL extensions for Go
robfig/cron Cron scheduler
zerolog Structured logging
semver Semantic version parsing

Frontend Development

cd ui

# Install dependencies
pnpm install

# Development server (http://localhost:5173)
pnpm dev

# Type checking
pnpm tsc

# Linting
pnpm lint

# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Build for production
pnpm build

Tech Stack

  • React 19
  • TypeScript
  • Vite
  • React Router
  • Vitest + React Testing Library

API Proxy

During development, the Vite dev server proxies /api requests to http://localhost:8080. This is configured in ui/vite.config.ts.

Database

stale uses SQLite for simplicity. The database file is stored in DATA_DIR (default: ./data).

Schema Migrations

Migrations run automatically on startup. Schema is defined in internal/repository/.

Adding a New Ecosystem

To add support for a new package manager:

  1. Create a new client in internal/service/{ecosystem}/
  2. Implement the registry client interface:
    type Client interface {
        GetLatestVersion(ctx context.Context, name string) (string, error)
    }
  3. Update internal/service/scanner/scanner.go to:
    • Add manifest file detection
    • Parse the manifest format
    • Call the new registry client
  4. Update the frontend to display the new ecosystem

Testing

Backend Tests

# All tests
go test ./...

# Specific package
go test ./internal/service/scanner/...

# With verbose output
go test -v ./...

Frontend Tests

cd ui

# Watch mode
pnpm test

# Single run
pnpm test:run

# Coverage report
pnpm test:coverage

Docker Build

# Build image
docker build --no-cache -t jiin724/stale:latest .

# Push to registry
docker push jiin724/stale:latest

The Dockerfile uses multi-stage builds:

  1. Build frontend with Node.js
  2. Build backend with Go
  3. Create minimal runtime image with Alpine

Clone this wiki locally