diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml
new file mode 100644
index 00000000..b03d45e3
--- /dev/null
+++ b/.github/workflows/links.yml
@@ -0,0 +1,61 @@
+name: Links
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ # Catch link rot on a schedule, not just when something changes.
+ schedule:
+ - cron: "0 6 * * 1" # Mondays, 06:00 UTC
+ workflow_dispatch:
+
+# Don't pile up redundant runs on the same branch.
+concurrency:
+ group: links-${{ github.ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ link-check:
+ name: Check links
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install Zola
+ env:
+ ZOLA_VERSION: "0.22.1"
+ run: |
+ curl -sSfL "https://github.com/getzola/zola/releases/download/v${ZOLA_VERSION}/zola-v${ZOLA_VERSION}-x86_64-unknown-linux-gnu.tar.gz" \
+ | sudo tar -xz -C /usr/local/bin
+ zola --version
+
+ - name: Build site
+ run: zola build
+
+ # Speed up repeat runs and avoid re-hitting every external host.
+ - name: Restore lychee cache
+ uses: actions/cache@v4
+ with:
+ path: .lycheecache
+ key: lychee-${{ github.sha }}
+ restore-keys: lychee-
+
+ - name: Check links
+ uses: lycheeverse/lychee-action@v2
+ with:
+ # Resolve internal links to the freshly built files: --root-dir maps
+ # root-relative paths (/blog/...), --remap maps the absolute
+ # corrode.dev URLs the templates emit. Everything else is checked
+ # over the network.
+ args: >-
+ --config lychee.toml
+ --cache
+ --max-cache-age 1d
+ --root-dir "${{ github.workspace }}/public"
+ --remap "https://corrode.dev file://${{ github.workspace }}/public"
+ "public/**/*.html"
+ "public/llms.txt"
+ fail: true
diff --git a/content/blog/rust-learning-resources-2026/index.md b/content/blog/rust-learning-resources-2026/index.md
index 4bf7638e..fb1538f2 100644
--- a/content/blog/rust-learning-resources-2026/index.md
+++ b/content/blog/rust-learning-resources-2026/index.md
@@ -133,7 +133,7 @@ It's like having a personal trainer for your Rust learning journey.
My workshops are designed to be hands-on and tailored to the needs of the participants.
I want people to walk away with a finished project they can extend.
-All course material is open source and freely available on GitHub:
+All the material is open source and free. You can browse the [full workshop catalog](/workshops/), or jump straight to a few favorites on GitHub:
- [Write Yourself a CLI](https://github.com/corrode/write-yourself-a-cli) - Create a tool to find files on your system
- [Write Yourself a Web App](https://github.com/corrode/write-yourself-a-web-app) - Build a small web app that shows weather data
diff --git a/content/learn/_index.md b/content/learn/_index.md
index a942f960..25e2f4ea 100644
--- a/content/learn/_index.md
+++ b/content/learn/_index.md
@@ -1,7 +1,3 @@
+++
-title = "Learn"
-description = "A collection of resources, case studies, and guides to help you learn Rust and adopt it in your organization."
-sort_by = "update_date"
-insert_anchor_links = "heading"
-template = "learn.html"
-+++
\ No newline at end of file
+redirect_to = "/learn/migration-guides"
++++
diff --git a/content/learn/migration-guides/_index.md b/content/learn/migration-guides/_index.md
index f7a3e927..889dfb6c 100644
--- a/content/learn/migration-guides/_index.md
+++ b/content/learn/migration-guides/_index.md
@@ -1,8 +1,17 @@
+++
title = "Rust Migration Guides"
-description = "Are you considering migrating from your current language to Rust? We've got you covered with guides that highlight the benefits of Rust and provide practical advice for making the switch. We'll help you navigate the transition."
+description = "Considering a move to Rust? These practical, language-by-language guides cover the real-world benefits, the common pitfalls, and the patterns that make the transition smooth (written from hands-on consulting experience)."
sort_by = "date"
insert_anchor_links = "heading"
+template = "migration-guides.html"
render = true
-transparent = true
+++
+
+Facing runtime crashes, long latencies, and rising infrastructure costs?
+That's why so many teams are considering a move to Rust.
+They want an actually helpful compiler that catches bugs in development, not production.
+But the hard part isn't the syntax.
+You need to map your language's idioms onto Rust's ownership model.
+These language-specific guides, drawn from hands-on consulting work, show
+where Rust pays off for your stack, how your concepts map across, and
+when Rust is not the right choice.
diff --git a/content/learn/migration-guides/cpp-to-rust/index.md b/content/learn/migration-guides/cpp-to-rust/index.md
index f7a03a53..3747294a 100644
--- a/content/learn/migration-guides/cpp-to-rust/index.md
+++ b/content/learn/migration-guides/cpp-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "C++ to Rust Cheat-Sheet"
+description = "Memory safety without a garbage collector: a side-by-side map of C++ idioms and type equivalents to their Rust counterparts, from RAII to ownership."
date = 2025-05-17
updated = 2026-02-25
template = "article.html"
diff --git a/content/learn/migration-guides/go-to-rust/index.md b/content/learn/migration-guides/go-to-rust/index.md
index 24620406..e2c1b405 100644
--- a/content/learn/migration-guides/go-to-rust/index.md
+++ b/content/learn/migration-guides/go-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "Migrating from Go to Rust"
+description = "An opinionated look at what Rust fixes (nil panics, missed data races, error handling, leaky generics), plus where to keep Go and how to migrate services incrementally."
date = 2026-05-21
updated = 2026-05-26
template = "article.html"
diff --git a/content/learn/migration-guides/java-to-rust/index.md b/content/learn/migration-guides/java-to-rust/index.md
index 80145664..46a9133d 100644
--- a/content/learn/migration-guides/java-to-rust/index.md
+++ b/content/learn/migration-guides/java-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "Migrating from Java to Rust"
+description = "An enterprise-grade playbook: planning the migration, running mixed Java/Rust codebases, and the mindset shifts from objects and inheritance to ownership."
date = 2024-12-09
updated = 2026-01-02
template = "article.html"
diff --git a/content/learn/migration-guides/python-to-rust/index.md b/content/learn/migration-guides/python-to-rust/index.md
index b4116c2c..c4714533 100644
--- a/content/learn/migration-guides/python-to-rust/index.md
+++ b/content/learn/migration-guides/python-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "Migrating from Python to Rust"
+description = "Where Python hits its limits (performance, type safety, deployment, resource usage) and how Rust addresses each without giving up Python's ergonomics."
date = 2024-12-13
updated = 2026-04-14
template = "article.html"
diff --git a/content/learn/migration-guides/scala-to-rust/index.md b/content/learn/migration-guides/scala-to-rust/index.md
index 71ab163a..2d081ba0 100644
--- a/content/learn/migration-guides/scala-to-rust/index.md
+++ b/content/learn/migration-guides/scala-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "Migrating from Scala to Rust"
+description = "The business case for leaving the JVM: adoption momentum, rock-solid backward compatibility, and tooling, compared honestly against Scala and Clojure."
date = 2024-12-09
template = "article.html"
draft = false
diff --git a/content/learn/migration-guides/typescript-to-rust/index.md b/content/learn/migration-guides/typescript-to-rust/index.md
index e03aabc0..8025348b 100644
--- a/content/learn/migration-guides/typescript-to-rust/index.md
+++ b/content/learn/migration-guides/typescript-to-rust/index.md
@@ -1,5 +1,6 @@
+++
title = "Migrating from TypeScript to Rust"
+description = "You already think in types. This guide maps TypeScript's interfaces, union types, and Promises straight onto Rust's traits, enums, and async."
date = 2024-12-13
updated = 2026-04-10
template = "article.html"
diff --git a/content/learn/workshops/_index.md b/content/learn/workshops/_index.md
new file mode 100644
index 00000000..54096577
--- /dev/null
+++ b/content/learn/workshops/_index.md
@@ -0,0 +1,3 @@
++++
+redirect_to = "/workshops"
++++
diff --git a/content/migrate/_index.md b/content/migrate/_index.md
new file mode 100644
index 00000000..25e2f4ea
--- /dev/null
+++ b/content/migrate/_index.md
@@ -0,0 +1,3 @@
++++
+redirect_to = "/learn/migration-guides"
++++
diff --git a/content/workshops/_index.md b/content/workshops/_index.md
new file mode 100644
index 00000000..97abe895
--- /dev/null
+++ b/content/workshops/_index.md
@@ -0,0 +1,12 @@
++++
+title = "Rust Workshops"
+description = "Hands-on, project-based Rust workshops from corrode. The materials are free and open on GitHub. Work through them solo, or book one for your team."
+template = "workshops.html"
+insert_anchor_links = "heading"
++++
+
+My workshops are hands-on: instead of toy snippets, you learn idiomatic Rust by
+writing real code. Whether that's building an actual thing (a CLI, a shell, a web
+app, a test suite) or solving interactive exercises Rustlings-style. Every
+workshop is free and open-source on GitHub, spans beginner to advanced, and can
+be booked as a live, tailored session for your team, on-site or remote.
diff --git a/data/workshops.toml b/data/workshops.toml
new file mode 100644
index 00000000..f14631ab
--- /dev/null
+++ b/data/workshops.toml
@@ -0,0 +1,77 @@
+# Workshops shown on the Workshops page (/workshops), in listed order.
+# The interactive course leads, then the repo workshops (Beginner first).
+#
+# Each entry is self-contained: `tags` and `meta` render as-is, so the course
+# and the repo workshops can show different details. `meta` is a point-in-time
+# snapshot (last checked 2026-06) — refresh it now and then. `pick` is a
+# one-line "who is this for" nudge. `image` is the card thumbnail.
+
+[[workshop]]
+title = "A Beginner's Guide to Rust"
+url = "https://course.corrode.dev/"
+description = "An interactive course you take in your browser: write real code, get instant compiler feedback, and build fluency one small exercise at a time."
+pick = "Small exercises with instant feedback."
+level = "Beginner"
+tags = ["Interactive", "In your browser"]
+meta = "★ 12 · 20+ exercises · Free"
+image = "https://opengraph.githubassets.com/main/corrode/course"
+
+[[workshop]]
+title = "Learning Rust by Counting Words"
+url = "https://github.com/corrode/learning-rust-by-counting-words"
+description = "Build wc, a little tool that counts words, lines, and characters. A gentle, practical introduction to Rust."
+pick = "Start here if you've never written Rust and prefer a project-based approach."
+level = "Beginner"
+tags = ["Fundamentals", "2 hours"]
+meta = "★ 6 · Updated Aug 2024"
+image = "https://opengraph.githubassets.com/main/corrode/learning-rust-by-counting-words"
+
+[[workshop]]
+title = "Write Yourself a CLI"
+url = "https://github.com/corrode/write-yourself-a-cli"
+description = "Build a fast file finder and learn how to structure a real-world Rust CLI, plus a few advanced patterns along the way."
+pick = "Pick this if you want to build a real command-line tool from scratch."
+level = "Beginner"
+tags = ["CLI", "Half day"]
+meta = "★ 33 · Updated Apr 2025"
+image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-cli"
+
+[[workshop]]
+title = "Write Yourself Some Tests"
+url = "https://github.com/corrode/write-yourself-some-tests"
+description = "Learn to write effective, ergonomic tests in Rust, from unit tests to the patterns that keep a suite maintainable."
+pick = "Pick this if your code works but your tests feel messy or brittle."
+level = "Beginner"
+tags = ["Testing", "2–3 hours"]
+meta = "★ 6 · Updated Mar 2025"
+image = "https://opengraph.githubassets.com/main/corrode/write-yourself-some-tests"
+
+[[workshop]]
+title = "Writing Better Rust"
+url = "https://github.com/corrode/refactoring-rust"
+description = "A refactoring workshop: take working but rough Rust and reshape it into idiomatic, ergonomic, maintainable code, one step at a time."
+pick = "Pick this if you can write Rust but want it to read like an expert wrote it."
+level = "Intermediate"
+tags = ["Refactoring", "Half day"]
+meta = "★ 83 · Updated Jun 2026"
+image = "https://opengraph.githubassets.com/main/corrode/refactoring-rust"
+
+[[workshop]]
+title = "Write Yourself a Shell"
+url = "https://github.com/corrode/write-yourself-a-shell"
+description = "Build a working shell from scratch. A deep dive into intermediate Rust concepts and idiomatic code."
+pick = "Pick this if you want to go deep on systems concepts in Rust."
+level = "Intermediate"
+tags = ["Systems", "6 hours"]
+meta = "★ 44 · Updated Nov 2024"
+image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-shell"
+
+[[workshop]]
+title = "Write Yourself a Web App"
+url = "https://github.com/corrode/write-yourself-a-web-app"
+description = "Build a small web application with axum and Postgres to learn how the pieces of a Rust backend fit together."
+pick = "Pick this if you're building web backends with axum and Postgres."
+level = "Intermediate"
+tags = ["Web", "Half day"]
+meta = "★ 31 · Updated Mar 2025"
+image = "https://opengraph.githubassets.com/main/corrode/write-yourself-a-web-app"
diff --git a/lychee.toml b/lychee.toml
new file mode 100644
index 00000000..ff3d9bd6
--- /dev/null
+++ b/lychee.toml
@@ -0,0 +1,45 @@
+################################################################################
+# lychee link checker configuration.
+#
+# Used by .github/workflows/links.yml against the built site in ./public.
+# Internal links (corrode.dev and root-relative) are remapped to the local
+# build in CI, so this run validates both internal wiring and external links.
+#
+# Docs: https://github.com/lycheeverse/lychee
+################################################################################
+
+# Be patient with slow or rate-limited hosts before giving up.
+max_retries = 2
+retry_wait_time = 3
+timeout = 20
+max_concurrency = 12
+
+# Plenty of hosts answer automated traffic with 403/429 even when the link is
+# fine. 405 means the URL exists but doesn't allow GET/HEAD (e.g. the
+# newsletter form's POST-only endpoint). Treat all of these as a pass.
+accept = ["200..=299", "403", "405", "429"]
+
+# Look like a normal browser. Cuts down on bogus 403s from bot-averse hosts.
+user_agent = "Mozilla/5.0 (compatible; corrode-link-check; +https://corrode.dev)"
+
+# The site obfuscates mailto: addresses with HTML entities, so skip them.
+include_mail = false
+
+# Don't try to reach localhost or private network addresses.
+exclude_all_private = true
+
+# Hosts that routinely block automated checks, or that we can't do anything
+# about even when they break. Skip them to keep the signal clean.
+exclude = [
+ # Internal links that carry a query string (e.g. podcast "?t=12:34" deep
+ # links). After the CI remap to local files, the "?" becomes part of the
+ # path and can't resolve. The target page is validated on its own.
+ '^file://.*%3F',
+ '^https?://(www\.)?linkedin\.com',
+ '^https?://(www\.)?twitter\.com',
+ '^https?://(www\.)?x\.com',
+ '^https?://t\.co/',
+ '^https?://(www\.)?reddit\.com',
+ '^https?://web\.archive\.org',
+ '^https?://([a-z0-9-]+\.)?amazon\.[a-z.]+',
+]
diff --git a/sass/_learn.scss b/sass/_learn.scss
index 0bbc80d7..a26085df 100644
--- a/sass/_learn.scss
+++ b/sass/_learn.scss
@@ -1,151 +1,209 @@
-.learn-sections {
- margin: 40px 0;
+/* ===== Learn hub: resource directory =====
+ Built on the shared .list-row component (see _list.scss), same as the
+ podcast list. Only the row *content* (thumbnail, tags, level, pick, meta)
+ is specific to Learn — there is no special list container. */
+
+.learn-section {
+ display: block;
+ margin: 0 0 2.5rem;
}
-.learn-list {
- list-style-type: none;
- padding: 0;
- margin-top: 30px;
- margin-bottom: 60px;
- border: 1px solid $heroDark;
- border-radius: 8px;
+.section-intro {
+ margin: 0.4rem 0 1rem;
+ opacity: 0.85;
+ line-height: 1.5;
+ font-size: 0.95em;
}
-.learn-list li {
- margin-bottom: 0;
- border-bottom: 1px solid $heroDark;
+.resource-list {
+ margin-bottom: 1rem;
+}
- &:hover {
- background-color: $brightScndLight;
+/* Extra leading column (thumbnail or logo) on top of the base 1fr/auto grid. */
+.resource-row.has-thumb,
+.resource-row.has-logo {
+ grid-template-columns: auto 1fr auto;
+}
- .chevron {
- transform: translateX(4px) rotate(270deg);
- }
- }
+/* Thumbnail (repo / product preview). */
+.resource-thumb {
+ width: 170px;
+ aspect-ratio: 2 / 1;
+ flex-shrink: 0;
+ border-radius: 8px;
+ overflow: hidden;
+ background-color: rgba($brightPrim, 0.05);
- &:last-child {
- border-bottom: none;
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
}
}
-.learn-link {
- display: block;
- text-decoration: none;
- color: inherit;
- padding: 30px;
-}
-
-.learn-item {
+/* Small language logo (migration guides). */
+.resource-logo {
+ width: 30px;
+ height: 30px;
+ flex-shrink: 0;
display: flex;
- justify-content: space-between;
align-items: center;
- gap: 40px;
+ justify-content: center;
+
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ }
}
-.learn-item img {
- width: 200px;
- border-radius: 8px;
- object-fit: contain;
- flex-shrink: 0;
+.resource-row-desc {
+ margin: 0.15rem 0 0;
+ font-size: 0.9rem;
+ line-height: 1.45;
+ color: rgba($brightPrim, 0.72);
}
-.learn-content {
+.resource-tags {
display: flex;
- flex-direction: column;
- justify-content: center;
- flex: 1; // Let the content take available space
- padding: 20px 0; // Consistent vertical padding
+ flex-wrap: wrap;
+ gap: 0.4rem;
+ margin-top: 0.6rem;
}
-.learn-description {
- font-size: 0.9em;
- opacity: 0.8;
- line-height: 1.4;
- margin-top: 15px;
- margin-bottom: 15px;
+.resource-tag {
+ font-family: JetBrainsMono;
+ font-size: 0.7rem;
+ font-weight: 500;
+ line-height: 1;
+ padding: 4px 8px;
+ border-radius: 4px;
+ background-color: rgba($brightPrim, 0.06);
+ color: rgba($brightPrim, 0.7);
+}
+
+/* Difficulty level, highlighted with a colour-coded dot. */
+.resource-level {
+ color: rgba($brightPrim, 0.85);
+ font-weight: 600;
}
-.learn-title {
- font-weight: bold;
- font-size: 1.3em;
- margin-bottom: 8px;
+.resource-level::before {
+ content: "●";
+ margin-right: 5px;
+ font-size: 0.85em;
+ color: #999;
}
-.learn-subtitle {
- opacity: 0.7;
- margin-left: 8px;
+.resource-level--beginner::before {
+ color: #2da44e;
}
-.card-item {
- display: flex;
- align-items: center;
- gap: 24px;
- padding: 12px 0;
+.resource-level--intermediate::before {
+ color: #bf8700;
}
-.card-logo-wrapper {
- width: 48px;
- height: 48px;
- flex-shrink: 0;
- display: flex;
- align-items: center;
- justify-content: center;
+.resource-level--advanced::before {
+ color: $brightScnd;
}
-.card-img {
- width: 100%;
- height: auto;
- object-fit: contain;
+.resource-pick {
+ margin: 0.4rem 0 0;
+ padding-left: 0.6rem;
+ border-left: 2px solid $brightBgrd;
+ font-size: 0.88rem;
+ font-weight: 500;
+ line-height: 1.4;
+ color: rgba($brightPrim, 0.85);
}
-.card-content {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 4px;
- min-width: 0;
+.resource-meta {
+ margin-top: 0.55rem;
+ font-family: JetBrainsMono;
+ font-size: 0.76rem;
+ color: rgba($brightPrim, 0.55);
}
-.card-title {
+.view-all {
+ display: inline-block;
+ margin-top: 0.25rem;
font-weight: 600;
- font-size: 1.05rem;
+ font-size: 0.9rem;
}
-.card-meta {
- font-size: 0.85rem;
- opacity: 0.6;
- font-family: JetBrainsMono;
+/* Page hero — a centered, decorative illustration (transparent background),
+ contained rather than cropped. Used on the Migrate and Workshops pages. */
+.page-hero {
+ margin: 1.5rem auto 0.5rem;
+ max-width: 520px;
+
+ img {
+ width: 100%;
+ height: auto;
+ display: block;
+ }
}
-@media (max-width: 768px) {
- .learn-item {
- flex-direction: column;
- align-items: flex-start;
+/* Workshops sub-page CTA — a plain bordered box, like other boxed content. */
+.workshops-cta {
+ margin: 3rem 0 1rem;
+ padding: 2.25rem;
+ border: 1px solid rgba($heroDark, 0.15);
+ border-radius: 8px;
+ text-align: center;
+
+ h2 {
+ margin-top: 0;
+ border-bottom: none;
}
- .learn-item img {
- width: 100%;
- height: auto; // Let height adjust proportionally
- max-height: 200px; // Cap the height
- margin-bottom: 15px;
+ p {
+ max-width: 520px;
+ margin: 0 auto 1.5rem;
+ line-height: 1.6;
}
+}
- .learn-content {
- padding: 0;
+@media (max-width: 768px) {
+ .resource-row.has-thumb,
+ .resource-row.has-logo {
+ grid-template-columns: 1fr;
}
- .learn-link {
- padding: 20px;
+ .resource-thumb {
+ width: 100%;
+ aspect-ratio: 2.2 / 1;
}
}
@media (prefers-color-scheme: dark) {
- .learn-list {
- color: white;
- border: 1px solid rgba(white, 0.5);
+ .resource-row-desc {
+ color: rgba(white, 0.72);
+ }
+
+ .resource-tag {
+ background-color: rgba(white, 0.08);
+ color: rgba(white, 0.72);
+ }
+
+ .resource-level {
+ color: rgba(white, 0.9);
+ }
+
+ .resource-pick {
+ color: rgba(white, 0.85);
+ }
+
+ .resource-meta {
+ color: rgba(white, 0.5);
+ }
+
+ .resource-thumb {
+ background-color: rgba(white, 0.06);
}
- .learn-list li {
- border-bottom: 1px solid rgba(white, 0.5);
+ .workshops-cta {
+ border-color: rgba(white, 0.15);
}
}
diff --git a/static/hero/migration.svg b/static/hero/migration.svg
new file mode 100644
index 00000000..593859f5
--- /dev/null
+++ b/static/hero/migration.svg
@@ -0,0 +1,2207 @@
+
+
+
+
diff --git a/static/hero/workshop.svg b/static/hero/workshop.svg
new file mode 100644
index 00000000..d62b3915
--- /dev/null
+++ b/static/hero/workshop.svg
@@ -0,0 +1,6660 @@
+
+
+
+
diff --git a/static/llms.txt b/static/llms.txt
new file mode 100644
index 00000000..7446926e
--- /dev/null
+++ b/static/llms.txt
@@ -0,0 +1,45 @@
+# Corrode Rust Consulting
+
+> Corrode is a friendly, professional Rust consulting and training company founded by Matthias Endler, based in Düsseldorf, Germany. We help teams adopt Rust, migrate existing systems to it, and write idiomatic, maintainable, production-grade code.
+
+We also publish a large body of free, open material for the wider Rust community: in-depth migration guides, hands-on workshops, a podcast, and an extensive blog about idiomatic Rust.
+
+## Consulting & Services
+
+- [Consulting & Training](https://corrode.dev/services/): Scoped Rust engagements: code review, architecture, training, and migration support.
+- [Why Rust?](https://corrode.dev/blog/why-rust/): The case for adopting Rust, for engineers and decision makers.
+- [Business Inquiries](https://corrode.dev/quote/): Request a quote or discuss a project.
+
+## Migration Guides
+
+Practical, language-by-language guides for teams moving to Rust.
+
+- [Migration Guides (overview)](https://corrode.dev/learn/migration-guides/): Index of all language-to-Rust migration guides.
+- [Go to Rust](https://corrode.dev/learn/migration-guides/go-to-rust/): What Rust fixes (nil panics, missed data races, error handling, leaky generics), and how to migrate Go services incrementally.
+- [Python to Rust](https://corrode.dev/learn/migration-guides/python-to-rust/): Where Python hits its limits (performance, type safety, deployment) and how Rust addresses each.
+- [TypeScript to Rust](https://corrode.dev/learn/migration-guides/typescript-to-rust/): Mapping TypeScript's interfaces, union types, and Promises onto Rust's traits, enums, and async.
+- [Java to Rust](https://corrode.dev/learn/migration-guides/java-to-rust/): An enterprise playbook covering mixed codebases and the shift from objects and inheritance to ownership.
+- [Scala to Rust](https://corrode.dev/learn/migration-guides/scala-to-rust/): The business case for leaving the JVM: adoption, backward compatibility, and tooling.
+- [C++ to Rust](https://corrode.dev/learn/migration-guides/cpp-to-rust/): Memory safety without a garbage collector: a side-by-side idiom and type cheat-sheet.
+
+## Workshops & Courses
+
+- [Rust Workshops](https://corrode.dev/workshops/): Hands-on, project-based workshops. Materials are free and open on GitHub; each can also be delivered live for your team.
+- [A Beginner's Guide to Rust](https://course.corrode.dev/): A free interactive course you take in your browser, with real code and instant compiler feedback.
+
+## Tools
+
+- [Rust Search](https://search.corrode.dev/): A search engine over the best Rust blog posts, talks, papers, and docs.
+- [Rust Tool Index](https://tools.corrode.dev/): Opinionated, curated tooling for every kind of Rust project, with honest trade-offs.
+
+## Writing & Media
+
+- [Blog](https://corrode.dev/blog/): Articles on idiomatic Rust, performance, testing, maintenance, and the ecosystem.
+- [Rust in Production (Podcast)](https://corrode.dev/podcast/): Interviews with engineers running Rust in production at companies large and small.
+- [Case Studies](https://corrode.dev/learn/case-studies/): Real-world stories of teams adopting Rust.
+
+## Optional
+
+- [Idiomatic Rust Resources](https://corrode.dev/blog/idiomatic-rust-resources/): A community-built, searchable collection of material for writing idiomatic Rust.
+- [Rust Learning Resources](https://corrode.dev/blog/rust-learning-resources-2026/): Curated workshops and tutorials for professional developers getting up to speed.
+- [Legal Notice](https://corrode.dev/legal/): Imprint and legal information.
diff --git a/templates/base.html b/templates/base.html
index cf74a6a9..d4b5236a 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -144,9 +144,15 @@
- Whether you are just starting out with Rust or looking to master
- advanced concepts, these curated resources will help you level
- up your skills.
-
-
- {% set sorted_pages = section.pages | filter(attribute="draft",
- value=false) %} {% set case_studies = sorted_pages |
- filter(attribute="extra.series", value="Company Case Studies") %} {%
- if case_studies %}
-
Company Case Studies
-
- What are the challenges and opportunities that companies face
- when adopting Rust? What advice do they have for others
- considering Rust? Read on to find out!
-
- Are you considering migrating your codebase to Rust? These
- guides will help you understand the process and make the
- transition as smooth as possible. Pick your current language
- below:
-
+ A move to Rust is easier with someone who has done it
+ before. We help teams scope the work, de-risk the rewrite,
+ and bring their engineers up to speed.
+