Development Stack¶
Languages, frameworks, and frontend methodology for Silver Frog.
Last Updated: January 2026 Status: Draft
Principles¶
- Simplicity over complexity - Avoid over-engineering, prefer straightforward solutions
- Server-first rendering - Minimize client-side JavaScript
- Team expertise - Leverage existing Elixir/Phoenix knowledge
- Single binaries when needed - Go for CLI tools and standalone services
Languages¶
| Language | Use Case | Notes |
|---|---|---|
| Elixir | Primary backend, web apps | Team has expertise, Phoenix framework |
| Go | CLI tools, microservices, single binaries | Fast compilation, easy deployment |
Elixir¶
Primary language for all web applications and backend services.
- Framework: Phoenix
- Real-time: Phoenix Channels
- Database: Ecto with PostgreSQL
- Background jobs: Oban
Go¶
Secondary language for specific use cases:
- CLI tools (internal tooling, automation)
- Small microservices requiring single binary deployment
- Performance-critical services
- Tools that need to run without runtime dependencies
Frontend¶
HTMX¶
Server-rendered HTML with HTMX for interactivity. Avoid heavy JavaScript frameworks.
Why HTMX:
- Minimal JavaScript footprint
- Server controls application state
- Works naturally with most backend frameworks
- Stateless requests, if compared to LiveView
CSS Methodology¶
Standards-based CSS using CUBE concepts with modern CSS features.
CUBE CSS¶
Composition, Utility, Block, Exception
| Layer | Purpose | Example |
|---|---|---|
| Composition | Layout primitives | .stack, .cluster, .sidebar |
| Utility | Single-purpose helpers | .text-center, .visually-hidden |
| Block | Component styles | .betting-slip, .card |
| Exception | State variations | [data-suspended], [data-loading] |
File Structure¶
styles/
├── main.css # Entry point, @layer order, imports
├── tokens.css # Design tokens (CSS custom properties)
├── reset.css # Modern reset
├── composition.css # Layout primitives
├── utilities.css # Helper classes
├── blocks/ # Components (one file each)
└── exceptions.css # Global state modifiers
Layer Cascade¶
/* main.css */
@layer reset, composition, utilities, blocks, exceptions;
@import "reset.css";
@import "tokens.css";
@import "composition.css";
@import "utilities.css";
@import "blocks/card.css";
@import "exceptions.css";
Native Nesting¶
CSS native nesting instead of BEM naming:
/* blocks/card.css */
@layer blocks {
.card {
background: var(--color-surface);
border-radius: var(--radius-md);
& .header {
padding: var(--space-sm);
}
& .body {
padding: var(--space-md);
}
}
}
Design Tokens¶
/* tokens.css */
:root {
--color-primary: #0066cc;
--color-surface: #ffffff;
--space-sm: 0.5rem;
--space-md: 1rem;
--radius-md: 4px;
}
[data-theme="dark"] {
--color-surface: #1a1a1a;
}
Summary¶
| Layer | Technology |
|---|---|
| Backend | Elixir + Phoenix |
| Real-time | Phoenix Channels |
| Interactivity | HTMX + vanilla JS |
| CSS | CUBE + @layer + nesting |
| Theming | CSS custom properties |
| CLI / Tools | Go |
| Database | PostgreSQL |