Software Architecture

Choosing a Programming Language — TS / Python / Java / Go / Rust

Choosing a Programming Language — TS / Python / Java / Go / Rust

About this article

This article is the first deep dive in the “Software Architecture” category of the Architecture Crash Course for the Generative-AI Era series, covering how to choose a programming language.

“The language ties down the framework, and the framework ties down who you can hire.” Once chosen, it binds the project for a decade — a hard-to-undo decision. The article covers the major nine languages (TypeScript, Python, Java, C#, Go, Rust, Ruby, PHP, C/C++) and selection criteria across the four axes of scale, use case, talent market, and AI-generation accuracy.

What is programming-language selection in the first place

Programming-language selection is, in a nutshell, “deciding which language to write your system in.”

Imagine learning a foreign language. English (TypeScript / Python) has the most speakers and resources; German (Java) has strict grammar and suits large enterprises; Latin (C / C++) is classical and fast but extremely hard to learn. Once you start writing in a language, all of the team’s talent, libraries, and know-how accumulate around it, and switching to another language later costs as much as “retranslating every paper you’ve ever written.”

Why language selection matters

What happens if language selection is taken lightly? If no one on the market can write that language in 5 years, you can’t hire or hand off — the system becomes technically stranded. Today is the era of picking the right language per use; mixing different languages for frontend and backend is normal.

Language selection is a One-way Door on par with overall structure. Decide it with a 5- and 10-year talent-market view.

”How many people will be writing this in 5 years?”

Old-school enterprise backend was Java-dominant; today is the era of picking the right language per use. Web systems standardly mix different languages on frontend (browser) and backend (server).

Computers natively understand only machine code. Programming languages are how humans drive them — source code gets translated to machine code by a compiler for execution.

Language selection, like overall structure, is a One-way Door. Decide it with a 5- and 10-year talent-market view.

Execution-style classification

Languages split by execution style into three groups. The style sets the trade-off between processing speed and development speed — the underlying property behind language selection.

flowchart LR
    SRC([Source code])
    COMP["Compiled<br/>C / C++ / Rust / Go"]
    INTR["Interpreted<br/>Python / Ruby / PHP"]
    JIT["JIT<br/>Java / C# / JavaScript"]
    SRC --> COMP --> MC1[Machine code<br/>fast in production]
    SRC --> INTR --> MC2[Sequential exec<br/>fast development]
    SRC --> JIT --> IL[Intermediate language] --> MC3[Compiled at runtime<br/>middle ground]
    classDef src fill:#fef3c7,stroke:#d97706;
    classDef comp fill:#dbeafe,stroke:#2563eb;
    classDef intr fill:#fae8ff,stroke:#a21caf;
    classDef jit fill:#f0f9ff,stroke:#0369a1;
    classDef out fill:#dcfce7,stroke:#16a34a;
    class SRC src;
    class COMP comp;
    class INTR intr;
    class JIT,IL jit;
    class MC1,MC2,MC3 out;
Execution styleLanguagesMechanism
CompiledC, C++, Rust, GoTranslated to machine code ahead of time. Fast, but recompile on every change
InterpretedPython, Ruby, PHPRead and execute line by line. Immediate feedback, but slow
JITJava, C#, JavaScriptBuild intermediate language; compile at runtime. OS-independent and reasonably fast

Compiled is “production performance,” interpreted is “development cycle speed.” JIT (Just-In-Time compiler — turns into machine code on the fly at runtime) is the middle-ground compromise.

C / C++

C (1972) is one of the earliest programming languages; the simple structure produces extremely fast execution. Lacking automatic memory management and OO, developers handle those manually.

C++ (1983) extends C with memory management and OO under the “zero-overhead principle,” maintaining C-comparable speed. Since 2011, modern features ship every 3 years; still active.

StrengthsWeaknesses
Overwhelming execution speed and stabilityNo automatic memory management (C)
Strong on hardware controlExtremely high learning difficulty
Massive library legacy (C++)Verbose, low readability

Main uses: embedded, OS / system software, AI library cores (PyTorch, TensorFlow), high-end games (Unreal Engine).

C’s domains are being replaced by Rust at speed. C/C++ won’t disappear due to the legacy footprint, but priority for new projects is dropping.

C# / .NET

C# (2000, Microsoft) is a cross-platform language with garbage collection and OO. Runs on Windows, Linux, Mac, iOS, Android, etc., though without C/C++ compatibility.

Microsoft maintains it actively with modern features. Excellent affinity with Microsoft products and Azure; broadly used from web apps to enterprise systems. Standard language for the Unity game engine — adopted in many mobile and console titles.

StrengthsMain uses
Excellent fit with Microsoft / AzureApps using Microsoft services
Good balance of performance and productivityGeneral web apps (ASP.NET Core)
No conspicuous weaknessesGame development (Unity standard)

C# is the default candidate where Microsoft services are central.

Java

Java (1996, Sun Microsystems; Oracle since 2010) provides OO, multi-threading, garbage collection, and runs on the JVM (Java Virtual Machine), making it OS-independent with high speed and stability.

Long-dominant in enterprise systems, still active. Updated semi-annually with cloud-optimization features. Spring family is mature, the standard for business app development.

License trap

Java has two licenses. OpenJDK is free open source like other languages; Oracle JDK commercial use requires per-employee licensing.

The fees are extremely high, calculated including non-developers. A 1,000-employee company pays around $200k/year; 30,000 employees pays around $2.4M/year. Oracle JDK support includes legal protection, support for older versions, and 24/7 phone support — often required by compliance at public-sector and financial firms.

LicenseCostMain rationale
OpenJDKFree (open source)General use
Oracle JDKAnnual license fee (high)Public sector / financial support requirements

Companies are migrating to free OpenJDK-compatible Amazon Corretto. Reasons to deliberately pick Oracle JDK are shrinking.

Oracle JDK costs license fees in commercial use. Amazon Corretto / Eclipse Temurin are the alternative defaults.

Python

Python (1991) provides functionality similar to other major languages, with “readability-first design” as the defining trait. Less code than Java or C#, with mandatory indentation-based blocks producing readable code regardless of who writes it.

Strong community, with the richest libraries especially in AI and data science — AI development effectively standardizes on Python. Interpreted, so raw speed is slow; but most libraries it calls are written in C/C++, so actual execution isn’t that slow.

StrengthsWeaknesses
Overwhelming readabilityRaw speed is somewhat slow
Effective standard in AI / data analysisDynamic typing weakens large-scale projects
Low learning costGIL (Global Interpreter Lock — restricts to one thread at a time)
Extremely rich libraries

Main uses: AI / ML / data analysis, general web apps (Django, FastAPI).

In AI / data science, no other language is in serious contention.

Ruby / PHP — current status of scripting languages

Ruby (1995, Yukihiro Matsumoto) is famous for “Ruby on Rails.” Rails generates feature scaffolding with one command and lets you build web app prototypes fastest by following conventions. Rails itself is heavy, so it’s a poor fit for FaaS (Function as a Service) and microservices; selection opportunities outside web are decreasing.

PHP (1995) was born for web, embedded in HTML to generate dynamic pages — explosively popular. WordPress, powering ~75% of websites globally, is in PHP — still the largest backend language by deployment count. PHP 8+ added JIT and improved typing; Laravel and Symfony are mature.

LanguagePosition
Ruby on RailsStrong choice for individuals / small teams launching web apps fastest
PHP + LaravelWordPress projects, small/mid web sites, existing PHP maintenance

Active new-project selection has decreased, but the legacy is huge so they remain major languages for now.

JavaScript

JavaScript (1995, Brendan Eich at Netscape, ~10 days) is the browser-side language. Spec is standardized as ECMAScript; complex parts from history persist, but yearly updates evolve it.

The biggest pivot: 2009’s Node.js. JavaScript became a general-purpose language outside the browser, opening “full-stack” with one language for frontend and backend. Event-driven and async I/O make it strong on high-concurrency web servers and AWS Lambda-style serverless.

StrengthsWeaknesses
De facto standard for frontendDynamic typing weak at large scale
Full-stack with Node.jsSpec complexity from history
Largest npm ecosystemAsync syntax is distinctive
Abundant learning resourcesLacks type safety

For backend, almost all projects have moved to TypeScript. Picking raw JS for backend outside small scripts is an obsolete choice.

TypeScript

TypeScript (2012, Microsoft) adds static typing and OO to JavaScript. Backwards-compatible with JS — existing JS code runs as-is. Compile-time type checks dramatically reduce runtime bugs.

For frontend, all major frameworks (Next.js, React, Vue, Angular) support TS — “TypeScript dominance” is the state. Backend runs on Node.js, Deno, Bun runtimes; especially BFF (Backend For Frontend, a frontend-specific intermediate API layer) and microservice adoption is surging. Sharing language and types between frontend and backend has a large team-productivity effect.

RuntimeTrait
Node.jsMost adopted, rich track record and info
DenoSuccessor by Node.js’s author. Strong on security and TS-native
Bun2022 high-speed runtime. Node.js compatible, several times faster startup

For new web projects, frontend and backend on TypeScript is the current default.

Rust

Rust (announced 2010 by Mozilla; 1.0 in 2015) is a compiled language guaranteeing memory safety. Without garbage collection, “ownership” prevents memory leaks and data races at compile time.

Steep learning curve, but once mastered you get C/C++-class execution speed and modern-language ergonomics. “Replacement candidate for C/C++” adoption is accelerating, ranking high in Stack Overflow’s “most loved language” survey.

Adoption areaExamples
SystemsLinux kernel (parts), Windows component adoption beginning
BrowsersFirefox rendering engine (Servo)
Web / infrastructureCloudflare Workers, Dropbox storage backend
WebAssemblyEffective first choice for Wasm targets
CLI / toolsReplacements for ripgrep, fd, esbuild

For new projects where performance and safety are absolute requirements, Rust is the most momentum-rich language now.

Go

Go (2009, Google) thoroughly pursued simplicity. Just 25 keywords; reachable to business-writing level in a week. Reportedly born from frustration with C++ builds taking 35+ minutes inside Google.

The biggest strength is overwhelming presence in cloud-native. Docker, Kubernetes, Terraform, Prometheus — most modern-infrastructure tools are written in Go. Statically compiled to a single binary and starts fast — strong fit for containers and FaaS, default for microservice API servers.

StrengthsWeaknesses
Low learning costPrioritizes simplicity over expressiveness
Lightweight concurrency via goroutinesLate generics support (came in 1.18)
Single-binary distributionFewer OO features
Fast startup, fits FaaS / containers

Adoption: Docker / Kubernetes / Terraform / Prometheus / etcd / Google, Uber, Netflix microservices.

For new cloud-native infrastructure, Go is the first candidate.

Major selection criteria

Language selection isn’t decided by trend or preference; multiple axes need joint evaluation matched to project requirements. Once chosen, the language binds the project for years, so decide carefully.

  1. Where the application runs (runtime / OS / cloud)
  2. Functional and non-functional requirements (performance, concurrency, consistency)
  3. Implementation effort (framework richness, dev speed)
  4. Available engineers (in-house skill, external talent market)

With AI-driven (vibe-coding) development spreading, AI compatibility has joined the criteria. Type-rich languages (TypeScript, Rust, Java) let AI infer intent accurately; languages with abundant training data (Python, JavaScript) generate higher-quality code.

Selection by case

New web app (API-centric, frontend-integrated)

TypeScript (Node.js / Bun). Share types between frontend and backend, balance dev speed with type safety. The most balanced current choice.

New web app (large-scale, enterprise, robustness focus)

Java / C#. Long operational track record, deep talent market, and mature frameworks (Spring Boot / ASP.NET Core). Still primary candidates in public sector and finance.

High-speed, low-resource servers

Rust / Go. For microservices and container-first, Go wins on startup speed and binary size. Rust comes in if extreme performance and memory safety are required.

AI / ML / data analysis

Python only. The library ecosystem is orders of magnitude ahead — practically no other choice. PyTorch, TensorFlow, pandas all assume Python.

Solo / small-team fastest prototype

Ruby on Rails / PHP + Laravel. The scaffold command auto-generates the skeleton; one person can launch a web app in a short period.

Embedded / OS / hardware control

C / C++ / Rust. New: Rust is a candidate; existing maintenance still requires C/C++.

Maintaining / extending existing systems

Continue with the existing language. Rewriting in a different language almost never pays.

Language × talent-market practical ladder

Knowing “how many will be writing this in 5 years” in numbers makes selection sharper. Approximate Japanese hiring-market sense as of April 2026:

LanguageDomestic engineer popHiring difficulty5-year continuationMain domainSuited case
JavaScript / TypeScript500k+Low (easiest to hire)ExpandingWeb, mobile, BFFWeb apps wanting type-sharing between front and back
Java400k+Low-midContinuingEnterprise / finance / publicEnterprise systems prioritizing robustness and long-term maintenance
Python300k+Low-midExpanding (AI demand)AI / data / webDevelopment centering on AI and data analysis
PHP200k+LowShrinkingWordPress / legacyWordPress projects or existing PHP asset maintenance
C# / .NET150k+MidContinuingUnity / Microsoft stackAzure-centric or Unity game development
Go50k+Mid-highExpandingCloud-native / microservicesContainer and microservice infrastructure
Ruby50k+Mid-highFlatRails legacy / startupsFastest prototype development with a small team
Rust10k+HighExpanding (niche)Systems / Wasm / infraAbsolute requirements for extreme performance and memory safety
Kotlin / Swift~50k eachMidContinuingMobile-onlyiOS / Android native app development

The empirical rule: “adopting a language with under 100k domestic engineers takes 6+ months to hire.” A startup posting “Rust required” sees applications drop 10x. For mid-career enterprise hiring, anything outside the TypeScript / Java / Python big three must be accepted as causing year-scale planning impacts.

Pick by numbers: “how many people will be writing this in 5 years.” Cases of niche-language teams stuck on hiring keep coming.

Language migration / selection traps

Forbidden moveWhy
”Big Bang Rewrite” — replacing language while rewritingNetscape 1998 lost 3 years on a rewrite and lost the browser wars. Phased migration (Strangler Fig) is the only realistic answer
Adopt an emerging language “because it’s trending” for an MVPEngineers don’t come; switching to another language during growth phase
Use dynamically typed languages (Python / Ruby) past mid-scaleType-absence cost surfaces 3 years later. Large-scale defaults to typed languages (TypeScript / Java / Go / Rust)
Use Oracle JDK commercially without checking the licensePer-employee × annual fee — at 1,000 employees, ~$200k/year. Amazon Corretto / Eclipse Temurin are the alternative defaults
5+ languages mixed in one projectMaintainers scatter; nobody understands the whole. Two languages (e.g. frontend TS + backend Go) is enough
Run non-LTS language versions in productionShort window before security patches end; yearly migration
”AI can write it, so a niche language is fine”AI accuracy scales with training-data volume; niche languages have hallucinations in generated code
Unifying all projects on one languageFrontend/backend in one language works, but forcing AI processing into TS too is unreasonable; right tool per use is the realistic answer
Selecting a language by trend aloneTrends are temporary; without checking “will the talent market still exist in 5 years?”, you ride the decline

Language selection is a One-way Door — you can’t go back once you start. With multiple candidates, always quantify on “hiring plan × 5-year talent market × AI-generation quality” before deciding.

“Fun to write” vanishes against hiring difficulty in 3 years.

AI decision axes

AI-era favorableAI-era unfavorable
TypeScript (types + info + full-stack)Dynamic languages (Perl, Ruby) instability at scale
Rust, Go (type safety, standardization)Custom DSLs, niche languages
Python (most training data)Custom extensions, in-house languages
Standard-framework complianceNiche implementations, custom patterns
  1. Narrow effective candidates by use (AI / web / high-perf / systems).
  2. Talent-market depth (can you hire 10 years from now?).
  3. AI-generation accuracy (type strength × info volume) for the final call.
  4. Continue if existing assets exist (rewriting almost never pays).

”How many in Japan write that?” (industry case)

When a junior engineer suggests “I want to use this in production” for a niche language they like, the senior architect asks “how many people in Japan write that?” and the proposer falls silent. This scene repeats in many places. The feeling of fun in writing and the management decision of being able to hire successors are different layers.

There are stories of young engineers underestimating Go’s then-niche status, proposing it for production, and going silent when their senior asked “how many on this team can write it after you?” Lesson: “language selection is technical decision and recruiting strategy at once.”

Niche languages should be enjoyed in personal study and validation projects; for production, default to “a language 5 years from now that thousands of people in Japan will still write.” The price of sharp selections is paid by the successor team.

Fun is cost. Talent is asset.

What you must decide — what’s your project’s answer?

Articulate your project’s answer in 1-2 sentences for each:

  • Main language (TypeScript / Python / Java / C# / Go / Rust, etc.)
  • Runtime / version (default to latest LTS)
  • Per-use additional languages (AI in Python, infra in Go, etc.)
  • Typing policy (TypeScript strict, Python type hints depth)
  • License check (Oracle JDK vs OpenJDK / Corretto, etc.)
  • Frameworks paired with the language (Spring / FastAPI / Next.js, etc.)
  • 5-10 year talent supply outlook

Recording the decision rationale

Language selection directly affects team composition, hiring, and maintenance cost, so documenting the rationale as an ADR (Architecture Decision Record) is essential. Here is a concrete example:

ItemContent
TitleAdopt TypeScript as the primary backend language
StatusAccepted
ContextSelecting a backend language for a new SaaS product. Frontend is already confirmed as React (TypeScript)
DecisionUnify the backend on TypeScript (Node.js LTS) as well
Rationale- Type definitions and validation logic can be shared with the frontend, boosting development efficiency
- 5 of 6 team members have TypeScript experience, minimizing additional learning cost
- The npm ecosystem is rich and AI code-generation accuracy is high
Rejected alternativesGo: no type sharing, increasing schema-sync cost between front and back. Python: weak type safety, more runtime errors at scale
OutcomeAdopt a front/back monorepo with a shared package for centralized type definitions

Even a decision that seems obvious at project start will inevitably spark “why TypeScript and not Go?” when team members rotate a year later. Having “why we chose this” visible at a glance later is the greatest value of an ADR.

Summary

This article covered how to choose a programming language — major-language traits, talent market, AI-era judgment.

Web -> TypeScript, AI / data -> Python, enterprise -> Java/C#, cloud-native -> Go, extreme performance -> Rust. The 2026 split. Niche languages stay in hobby; production leans on the mainstream. That saves both hiring and long-term maintenance.

The next article covers overall structure (monolith vs microservices vs modular monolith).

Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book

I hope you’ll read the next article as well.