# Swirl.jl - Interactive Julia Learning in the REPL 🌀

**URL:** <https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705>\
**Category:** Package Announcements\
**Tags:** announcement, repl, tutorials, teaching\
**Created:** [November 6, 2025, 10:25am UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705 "2025-11-06T10:25:15Z")\
**Posts on this page:** 8\
**Page:** 2

<div class="post-metadata">

**Author:** ![Alex\_Tantos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_tantos/32/10636_2.png) [@Alex\_Tantos](https://discourse.julialang.org/u/Alex_Tantos)\
**Post date:** [November 12, 2025, 12:01pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/21 "2025-11-12T12:01:06Z")

</div>

**Swirl.jl now supports multi-step code questions and full Markdown rendering! 🌀**

**Swirl.jl** has just been updated with two major improvements:

✨ **Multi-step questions** : you can now design exercises that require multiple code lines, with separate hints for each step. Perfect for walking learners through multi-part problems or short coding tasks.

📝 **Markdown rendering everywhere** : lessons, questions, hints, and menus are now displayed with Markdown formatting, making everything cleaner and easier to read directly in the REPL.

The built-in _Julia Basics_ course has been adapted to use these new features.  
You can check it out in action [here](https://youtu.be/aEboVhipEfg)

---

<div class="post-metadata">

**Author:** ![Alex\_Tantos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_tantos/32/10636_2.png) [@Alex\_Tantos](https://discourse.julialang.org/u/Alex_Tantos)\
**Post date:** [November 12, 2025, 12:01pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/22 "2025-11-12T12:01:33Z")

</div>

Thanks for the great suggestion!  
You can check out my latest post. I hope you’ll like the result.

There wasn’t really a strong reason those fields had to be `String`; I had chosen that early on because the classic runner simply used `println` everywhere. Now, **Swirl.jl** fully supports `Markdown.MD` in REPL mode, so lessons, questions and hints are all nicely rendered.

---

<div class="post-metadata">

**Author:** ![Alex\_Tantos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_tantos/32/10636_2.png) [@Alex\_Tantos](https://discourse.julialang.org/u/Alex_Tantos)\
**Post date:** [November 12, 2025, 12:04pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/23 "2025-11-12T12:04:56Z")

</div>

I love this idea! Running Swirl in a `ttyd` container is brilliant. The REPL likely exits because `ttyd` isn’t fully interactive yet, I guess(?) Could you try `swirl(use_repl_mode=:classic)` for now and see how it goes?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 18, 2025, 6:58pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/24 "2025-11-18T18:58:35Z")

</div>

21 posts were split to a new topic: [Reliability of AI coding tools](https://discourse.julialang.org/t/reliability-of-ai-coding-tools/133975)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 19, 2025, 2:39pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/25 "2025-11-19T14:39:29Z")

</div>

A post was merged into an existing topic: [Reliability of AI coding tools](https://discourse.julialang.org/t/reliability-of-ai-coding-tools/133975/32)

---

<div class="post-metadata">

**Author:** ![TheCedarPrince](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thecedarprince/32/17323_2.png) [@TheCedarPrince](https://discourse.julialang.org/u/TheCedarPrince)\
**Post date:** [November 19, 2025, 3:42pm UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/26 "2025-11-19T15:42:17Z")

</div>

Hey @Alex_Tantos,

I was thinking some more about Swirl.jl today and was curious: are you thinking about attending JuliaCon 2026 in Meinz? I am wondering if having some in-person hacking sessions could be fun.

Moreover, and perhaps a bit selfishly, over in JuliaHealth world we are beginning to start thinking about the JuliaHealth 2026 Mini-Symposium – I am thinking there may be some neat applications where Swirl.jl could be used for teaching/highlighting package use cases and crucially: workflows! 🤔

At any rate, hope all is well and thanks for the work here!

~ tcp 🌳

---

<div class="post-metadata">

**Author:** ![Alex\_Tantos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_tantos/32/10636_2.png) [@Alex\_Tantos](https://discourse.julialang.org/u/Alex_Tantos)\
**Post date:** [November 20, 2025, 10:30am UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/27 "2025-11-20T10:30:19Z")

</div>

Thanks so much for the message, really appreciated @TheCedarPrince .

Regarding JuliaCon 2026 in Mainz: it will mostly depend on whether I manage to put together our own minisymposium and secure the logistics around that. I’ll need to think about it a bit more, but if I do attend, then absolutely. Sitting down for some in-person hacking sessions would be a lot of fun.

About the JuliaHealth minisymposium: happy to hear that Swirl.jl came to mind in that context. About the “workflows” part: if I understand correctly, you’re referring to using Swirl to guide users through complete usage paths of JuliaHealth packages, not just individual functions, but the full sequence of steps that make up a typical workflow. If that is the case, that actually aligns very well with what I’m doing on the language-data side too: many linguistic and corpus-analysis tasks also follow multi-step pipelines (loading data, preprocessing, applying models or statistical functions, visualizing, interpreting)  
If there’s interest in having a presentation or demo on how Swirl can support workflow-oriented teaching for JuliaHealth packages, I’d definitely be open to discussing it. It could actually fit quite naturally with the kind of step-by-step REPL-based interaction Swirl encourages.

Let me know what ideas you have in mind. I’d love to explore them. Feel free to DM me anytime if that’s easier.

---

<div class="post-metadata">

**Author:** ![Alex\_Tantos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex_tantos/32/10636_2.png) [@Alex\_Tantos](https://discourse.julialang.org/u/Alex_Tantos)\
**Post date:** [November 21, 2025, 11:27am UTC](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705/28 "2025-11-21T11:27:50Z")

</div>

After some back-and-forth and much cleaner code with less Claude Sonnet intervention this time, we’ve now merged a PR where questions transition from symbol-based to type-based dispatch.

**Previously** , questions were created using symbol-based dispatch:

```julia-auto
Question("What is 2+2?", :code, 4, "Add the numbers")
Question("Welcome!", :message, nothing)
Question("Pick one:", :multiple_choice, 2, "hint", ["A", "B", "C"])

```

**Now** , we use explicit typed constructors:

```julia-auto
CodeQ(text="What is 2+2?", answer=4, hint="Add the numbers")
MessageQ(text="Welcome!")
ChoiceQ(text="Pick one:", choices=["A", "B", "C"], answer=2, hint="hint")

```

### New Question Types

The refactoring also introduces new question types:

- **`CodeQ`** - Single-step code questions (replaces `:code`)
- **`MultistepCodeQ`** - Multi-step code questions with step-by-step guidance
- **`MessageQ`** - Display-only messages (replaces `:message`)
- **`ChoiceQ`** - Single-choice questions (replaces `:multiple_choice`)
- **`MultipleChoiceQ`** - Multiple-selection questions
- **`StringQ`** - String matching with regex support
- **`NumericQ`** - Numeric answers with range checking

### Example: Multi-Step Code Questions

```julia-auto
MultistepCodeQ(
                text=md" **Good**! Bindings let you reuse values. Now create a binding `y` with the value `5`, then add `x` and `y` together.",
                answer=15,
                hint="",
                steps=[
                    md"Create a binding `y` with value `5`.",
                    md"Add `x` and `y` together."
                ],
                step_hints=[
                    md"Type: `y = 5`
Bindings let you refer to values for later use.",
                    md"Type: `x + y`
Remember: `x` is still `10` from the previous question!"
                ],
                setup="x = 10"
            )

```

Also, a few new features and changes were adopted that improve the experience such as the `<- in progress` and the `<- just completed` indicators.

UPDATE: The `README.md` has just been updated.  
UPDATE2: Here is a short new [yt demo](https://youtu.be/js0w_Hf-xwc) of the current state of the UI.

[Previous page](https://discourse.julialang.org/t/swirl-jl-interactive-julia-learning-in-the-repl/133705.md?page=1)
