PG-QR-000 · IT HELP · JULIA & PLUTO · REFERENCE GUIDE

Julia and Pluto Reference

Write, format, and explain a Pluto.jl notebook: Julia syntax, notebook Markdown, and the math and interactivity that connect them.

Author Polymath Global Published 2026-07-24 Updated 2026-08-17
Level Beginner to intermediate Core path 45-60 minutes Scope Language and notebook reference
Summary

This guide replaces two separate quick references with one page organized around what writing a Pluto.jl notebook actually involves: the notebook model itself, where Pluto's behavior surprises readers coming from ordinary Julia, the language, the notebook's Markdown, its math, and its interactivity. Sections 1-7 are the complete Beginner-to- intermediate core path. Sections 8-11 are Advanced material: multiple dispatch and type stability in more depth, reactive patterns beyond a single slider, accessible mathematics, and keeping a growing notebook maintainable.

Tooling disclosure. This guide was developed using a repository governance harness and AI-assisted research/curation workflow engineered by Joe Waller and enabled through OpenAI and Anthropic tooling. These tools support research and documentation, including source review, summarization, validation, and guide drafting, and do not replace the author's judgment.

1Notebook Fundamentals Core

A Pluto notebook is a sequence of cells. Each cell holds one piece of Julia code, and Pluto shows that code next to the value it produces -- a cell displays the value of its last expression automatically, with no print needed for a simple result.

A cell and its displayed value
radius = 3
area = pi * radius^2

That cell displays 28.274333882308138 automatically, because it is the value of the last (and only) expression in the cell. Section 2 covers what happens when you reach for println instead.

Prose lives in its own cells, written as a Markdown string using triple-quoted md"""...""" blocks. A notebook mixes code cells and Markdown cells freely -- neither has to come before the other.

A Markdown cell
md"""
## Circle area
We computed the area of a circle with radius $radius above.
"""

The other defining trait is reactivity: when you edit a cell, Pluto does not just re-run that cell -- it re-runs every other cell whose code depends on what changed, in whichever order the dependencies require. Cells can be arranged on the page in any order; Pluto determines execution order from the code itself, not from top-to-bottom position. Section 2 covers the sharpest edges of what that guarantee actually requires from your code.

2Where Pluto Differs from Ordinary Julia Core

Pluto runs real Julia, but its notebook model enforces a few rules an ordinary Julia session or a Jupyter notebook does not. Knowing these four before you write real code avoids the errors that catch nearly every new Pluto user in the first hour.

Each global variable can be defined in only one cell

Pluto's reactivity depends on knowing, unambiguously, which cell defines which variable. Assigning the same global name in two different cells is not a style issue -- Pluto disables one of the cells and reports a multiple-definitions error.

Fails: the same name assigned in two cells
# Cell A
x = 1

# Cell B
x = 2   # Pluto disables one of these cells

If two related values genuinely belong together, combine their assignments into one cell using a begin ... end block instead of splitting them across cells.

Fix: combine related assignments in one cell
begin
    x = 1
    y = x + 1
end
  • This rule applies to global assignments only -- a variable local to a function or a loop can be reused freely across cells.
  • If you see "multiple definitions for x," look for a second top-level assignment to that name and merge it with the first.

Pluto manages your packages automatically

You do not run Pkg.add before using a package in Pluto. Import it directly, and Pluto reads the notebook's code to work out which packages it needs, then installs and tracks them for you.

Using a package with no install step
using Plots   # Pluto installs Plots.jl automatically the first time this runs

Pluto stores the resulting Project.toml and Manifest.toml directly inside the notebook file itself, as two extra cells at the bottom you do not normally edit by hand. Every notebook gets its own isolated package environment, so packages you install in one notebook cannot silently affect another -- unlike a shared Jupyter kernel or a normal Julia REPL session, where packages live in one common environment unless you deliberately activate a different one.

Reactivity tracks code, not values -- mutations do not trigger it

Pluto decides what to re-run by analyzing which cells reference which variable names, not by watching values change at runtime. Re-assigning a variable triggers dependent cells to re-run; mutating it in place does not, because no cell's code actually changed.

Mutation alone does not re-run dependent cells
items = ["a", "b"]

# later, in another cell:
push!(items, "c")   # items is now length 3, but any cell that already
                     # displayed items will not automatically refresh

The common workaround is a small "dummy" trigger variable that you deliberately re-assign to force a re-run of anything that should reflect the mutation.

Forcing a re-run after a mutation
begin
    push!(items, "c")
    items_trigger = items_trigger + 1   # any cell using items_trigger now re-runs
end

print, println, and display do not write to the notebook

These functions write to the terminal that launched Pluto, not to the cell itself -- a notebook cell only ever shows the value of its own last expression. If you want a value visible in the notebook, make it the last thing the cell evaluates rather than printing it.

Show a value in the notebook, correctly
# Shows nothing useful in the notebook -- goes to the launching terminal instead
println("The area is $area")

# Shows the value in the notebook, because it is the cell's last expression
"The area is $area"

3Julia Language Essentials Core

The constructs every notebook eventually needs: conditionals, loops, collections, functions, dispatch, and handling errors without crashing the whole notebook.

Control flow

Conditionals and loops
if radius > 10
    "large circle"
elseif radius > 0
    "small circle"
else
    "not a circle"
end

for i in 1:5
    println(i)   # goes to the launching terminal -- see section 2
end

n = 5
while n > 0
    n -= 1
end

Collections

Arrays, dictionaries, structs, and comprehensions
values = [1, 2, 3]
push!(values, 4)

lookup = Dict("a" => 1, "b" => 2)

struct Point
    x::Float64
    y::Float64
end

squares = [v^2 for v in values]
doubled = map(v -> v * 2, values)
evens = filter(v -> iseven(v), values)

Tuple unpacking assigns several names from one expression at once, and is common enough in Pluto cells that it is worth knowing on sight: a, b = 1, 2.

Functions and multiple dispatch

Julia lets you define the same function name more than once, with a different method for each combination of argument types -- this is multiple dispatch, and it is one of the language's defining features. Section 8 covers why it also matters for performance.

Two methods of one function name
area(radius::Float64) = pi * radius^2
area(length::Float64, width::Float64) = length * width

area(3.0)        # calls the one-argument method: circle area
area(2.0, 5.0)   # calls the two-argument method: rectangle area

Handling errors with try/catch/finally

Wrap code that might fail in a try block, and handle the failure in a catch block instead of letting it stop the whole cell.

Catching a specific error
function safe_divide(a, b)
    try
        a / b
    catch e
        if isa(e, DivideError)
            "cannot divide by zero"
        else
            rethrow(e)
        end
    finally
        # runs whether or not an error occurred
    end
end
  • Check the caught exception's type with isa(e, SomeErrorType) rather than treating every error the same way.
  • rethrow(e) re-raises an error you did not intend to handle, instead of silently swallowing it.

4Writing Markdown in Pluto Core

Markdown cells (md"""...""", introduced in section 1) support the same core syntax you would use anywhere else, with two Pluto-specific extensions covered in section 5.

Core Markdown inside a Pluto cell
md"""
## A second-level heading

Use **bold** sparingly, and `inline code` for literal tokens like variable names.

- Bulleted list item
- Another item

1. Numbered step
2. Next step

> A blockquote for a quoted or emphasized aside.

[A descriptive link](https://plutojl.org/)

![Alt text describing the image](local-image.png)

| Column A | Column B |
|---|---|
| value | value |
"""

Fenced code blocks inside Markdown cells are for showing code as text, not for running it -- give them a language tag so they render with the right highlighting.

A fenced code block shown as text
md"""
```julia
area(radius::Float64) = pi * radius^2
```
"""
  • Use headings in descending order, matching the notebook's actual structure.
  • Give every image real alt text and keep local images alongside the notebook.
  • Keep tables simple -- a table that needs heavy formatting to stay readable is usually better as a short list.

5Math and Interpolation Core

Pluto renders Markdown math with KaTeX rather than MathJax, specifically because KaTeX supports interpolating live Julia values into an equation and numbering equations by their position in the notebook -- both of which a static math renderer cannot do.

Inline and display math
md"""
Inline: the area is $\pi r^2$.

Display, for a longer expression:
$$\pi r^2 = \pi \cdot r \cdot r$$
"""

A single $(value) interpolates a live Julia value directly into Markdown text -- the same interpolation syntax Julia strings use elsewhere in the language.

Interpolating a computed value into Markdown
md"""
With radius $(radius), the computed area is $(round(area, digits=2)).
"""
  • Prefer display math for anything longer than a short inline expression -- it reads far more clearly.
  • Define any Greek letters or unfamiliar symbols in the nearby prose the first time they appear.

The full LaTeX math syntax -- AMS environments, equation numbering, and accessible math publishing -- is its own dedicated guide: LaTeX Math Quick Reference.

6Interactivity and Plots Core

The @bind macro links an HTML input element to a Julia variable: whenever the input changes, every cell that uses the bound variable re-runs automatically. PlutoUI supplies the common input widgets so you rarely write the HTML by hand.

The PlutoUI widget catalog
using PlutoUI

@bind r Slider(1:10; default=3, show_value=true)
@bind label TextField(20, "default text")
@bind show_grid CheckBox(true)
@bind shape Select(["circle", "rectangle"])
@bind shapes MultiSelect(["circle", "rectangle", "triangle"])
@bind go Button("Recompute")
@bind confirmed_value confirm(Slider(1:100))   # only updates when confirmed, not live

confirm wraps any widget so it only sends its value on explicit confirmation rather than on every intermediate change -- useful when the bound cell triggers an expensive computation.

Plots.jl composes a chart from a base call plus mutating follow-up calls: plot starts a new plot, and functions ending in ! add to the existing one.

A slider-driven plot
using Plots

@bind r Slider(1:20; default=5, show_value=true)

theta = range(0, 2pi, length=200)
plot(r .* cos.(theta), r .* sin.(theta), label="circle, r=$r", aspect_ratio=:equal)
scatter!([0], [0], label="center")
hline!([0], label=false, linestyle=:dash)
  • Moving r's slider re-runs the plot cell automatically, because the cell reads r.
  • plot starts a new figure; scatter!, hline!, and vline! add to the one already open.

7Writing Readable Notebooks Core

These apply to both the Julia and the Markdown you write -- a notebook is read far more often than it is written.

  • Use a consistent heading hierarchy that matches how the notebook is actually organized, not just visual size.
  • Keep paragraphs and cells short -- one idea per cell makes reactivity easier to reason about, not just easier to read.
  • Limit list nesting to what a reader can track at a glance.
  • Avoid raw HTML inside Markdown cells when plain Markdown says the same thing.
  • Use fenced code blocks with a language tag for any code shown as text (section 4), never a bare Markdown paragraph.
  • Give every image real alt text, and keep local images alongside the notebook or in an approved child directory (repeated from section 4 because it is the most commonly skipped item).

8Multiple Dispatch and Type Stability Optional advanced

Section 3 introduced multiple dispatch as a way to write one function name with several type-specific methods. The reason it matters beyond readability is compilation: Julia compiles a specialized version of a method for the actual argument types it sees, and that specialization is what makes Julia fast without giving up the expressiveness of a dynamic language.

Type stability is the property that a function returns the same output type for a given combination of input types, every time. A type-stable function lets the compiler know the result type ahead of time and generate tight, C-like code; a type-unstable one forces Julia to check types at runtime and box and unbox values, which is where most avoidable performance loss in Julia code comes from.

Unstable vs. stable
# Unstable: the return type depends on a runtime value, not just the input type
function maybe_int(x)
    if x > 0
        return x          # returns whatever type x is
    else
        return 0           # always returns Int, even if x was a Float64
    end
end

# Stable: the return type is fixed by the input type alone
function always_float(x::Float64)
    return x > 0 ? x : 0.0
end

You do not need to chase type stability everywhere -- it matters most in code that runs many times, such as the body of a loop or a function called from a reactive cell that re-runs on every slider movement.

9Reactive Pluto Patterns Beyond @bind Optional advanced

Section 2's "dummy trigger" pattern generalizes: any time a cell's real effect is a mutation Pluto cannot see, a small re-assigned counter variable is what makes dependent cells re-run.

Combining several bound values in one reactive expression
@bind r Slider(1:20; default=5)
@bind color Select(["blue", "red", "green"])

# This cell re-runs whenever *either* r or color changes, because it reads both.
plot(r .* cos.(theta), r .* sin.(theta); color=Symbol(color))

Wrap an expensive bound widget in confirm (section 6) when its cell triggers real work -- a large computation or a network call -- so it only runs once per deliberate confirmation instead of on every intermediate slider position.

10Accessible Mathematics in Notebooks Optional advanced

The same accessibility practices covered on Accessibility and Dyslexia-Friendly Publishing apply directly inside a notebook.

  • Define every symbol in nearby prose the first time it appears (section 5) -- a screen reader announces a bare Greek letter as its own name, not its mathematical meaning.
  • Do not rely on color alone to distinguish plot series (section 6); pair color with a label, marker shape, or line style.
  • Prefer display math over dense inline math for any expression a reader needs time to parse.
  • Give every figure a caption that states what it shows, not just what it is titled.

11Maintainable Rich Notebook Layouts Optional advanced

A notebook that starts small tends to grow. These keep a larger notebook navigable instead of becoming a long scroll of near-duplicate cells.

  • Group related code into one begin ... end cell (section 2) when the pieces only make sense together, rather than splitting them for no reason.
  • Write a helper function once and call it from multiple cells instead of copy-pasting a computation.
  • Keep computation and display separate: compute a value in one cell, and format or plot it in a later one, so Pluto's dependency graph stays easy to follow.
  • Use section headings (section 7) to break a long notebook into named parts a reader can jump to from the table of contents Pluto generates automatically.

References

  1. [1] JuliaPluto. Reactivity -- how Pluto notebooks update automatically. The one-definition-per-variable rule and syntax-based reactivity. Verified 2026-08-17.
  2. [2] JuliaPluto. Packages -- built-in package management. Automatic per-notebook Project.toml/Manifest.toml handling. Verified 2026-08-17.
  3. [3] JuliaPluto. LaTeX. Inline and display math syntax inside Pluto Markdown cells. Verified 2026-08-17.
  4. [4] JuliaPluto. PlutoUI and @bind. How the @bind macro links UI elements to reactive variables. Verified 2026-08-17.
  5. [5] JuliaHub. PlutoUI.jl documentation. The full widget catalog: Slider, TextField, CheckBox, Select, MultiSelect, Button, confirm. Verified 2026-08-17.
  6. [6] JuliaPluto. Assign a variable more than once (issue #276). The begin...end workaround for combining related assignments. Verified 2026-08-17.
  7. [7] The Julia Language. Control Flow. Conditionals, loops, and exception handling syntax. Verified 2026-08-17.
  8. [8] Julia community documentation. Writing type-stable Julia code. Practical explanation of type stability's performance effect. Verified 2026-08-17.
  9. [9] JuliaPlots. Plots.jl documentation. The plot/scatter!/hline! composition pattern. Verified 2026-08-17.
  10. [10] Polymath Global. Julia_Programming_Guide.md. Original topic coverage this page consolidates. Snapshot verified 2026-07-24.
  11. [11] Polymath Global. Pluto_JL_Markdown_Guide.md. Original topic coverage this page consolidates. Snapshot verified 2026-07-24.