v0.413 tracks livelast build: current milestone
Learn a language by
mapping it
to the one you already use.
Guided learning tracks for experienced developers. Each track translates familiar mental models into the shapes, tradeoffs, and habits of a new language — no beginner-level detours.
~/langfor/pick-trackclick chips to refine
$langfor--from JavaScript/Node--to Rust
• from · what you know4 options
→
• to · what's next4 matches
↳/javascript-node-to-rust · Learn systems-language discipline from a JavaScript starting point.
•source chips set what you already know•target chips stay scoped to valid matches•open track jumps straight to the suggested path
02track matrix
Every supported pair, at a glance. Hover a row and column to inspect what is live, then jump straight into the matching transition.
from ↓to →
Go
Rust
Python
JavaScript
TypeScript
C#
Python
—
JavaScript
—
·
Go
—
·
·
·
Rust
—
·
·
·
↳ /python-to-rust · Learn ownership, enums, and compiler-guided design.
03featured tracks
Hand-picked starting points if you want a strong next step without browsing the full catalog first.
Most popular start
PythonGo
Move into a simpler, explicit compiled language.
A strong first comparison if you want a simpler compiled model without leaving backend work behind.
open track Biggest mindset shift
PythonRust
Learn ownership, enums, and compiler-guided design.
A deeper jump for developers ready to trade Python flexibility for compiler-guided design.
open track Lowest-friction upgrade
JavaScript/NodeTypeScript
Turn familiar JavaScript runtime code into safer, better-specified systems.
A pragmatic path when you already know the runtime and want better guarantees at the boundaries.
open track 04inside a lesson
Each lesson starts from a source-language instinct, then shows the target-language pattern that usually replaces it. Side by side. Same example, two minds.
python-to-go / 04 · syntax / error handling
From try/except→err != nil
Once the pattern clicks, Go error handling feels less like ceremony and more like a habit that keeps surprising control flow out of the codebase.
Python
def render_dashboard(user_id):
try:
profile = load_profile(user_id)
stats = load_stats(user_id)
except ProfileError as exc:
logger.warning("profile unavailable: %s", exc)
return None
return build_dashboard(profile, stats)Go
func renderDashboard(userID int) (*Dashboard, error) {
profile, err := loadProfile(userID)
if err != nil {
log.Printf("profile unavailable: %v", err)
return nil, err
}
stats, err := loadStats(userID)
if err != nil {
return nil, err
}
dashboard := buildDashboard(profile, stats)
return &dashboard, nil
}