[{"url":".","title":"index","description":"","tags":["welcome"],"text":""},{"url":"sidebar data/","title":"sidebar data","description":"","tags":[],"text":"Dict \"en\" Dict \"docs\" \"Introduction\" collections \"docs\" .pages ∩ collections \"introduction\" .pages, \"Pluto for education\" collections \"docs\" .pages ∩ collections \"education\" .pages, \"Using Pluto\" collections \"docs\" .pages ∩ collections \"navigation\" .pages, \"Writing a notebook\" collections \"docs\" .pages ∩ collections \"writing\" .pages, \"Reproducibility\" collections \"docs\" .pages ∩ collections \"reproducibility\" .pages, \"Editor\" collections \"docs\" .pages ∩ collections \"editor\" .pages, \"Publishing\" collections \"docs\" .pages ∩ collections \"publishing\" .pages, \"Advanced Widgets\" collections \"docs\" .pages ∩ collections \"advanced\" .pages ∩ collections \"widgets\" .pages, \"Advanced Internals\" collections \"docs\" .pages ∩ collections \"advanced\" .pages ∩ collections \"internals\" .pages, , \"examples\" \"Getting started\" collections \"examples\" .pages, , "},{"url":"workshop/","title":"JuliaCon 2025 Workshop","description":"","tags":["workshop"],"text":"JuliaCon 2025 WorkshopTo learn more about Pluto:Check out the Pluto.jl websitePluto is open source! You can give us a 🌟 on the GitHub repositoryThe new Pluto.jl documentation is a good way to learn more about what you can do with Pluto!InstallThis workshop, you will get started with Pluto! Follow these instructions to install Pluto:Installation instructions – do this during the workshop introduction!Already installed Pluto? Make sure you have the latest version (0.20.19). To update Pluto, you can update it with Pkg like any other package. More info:Update instructionsWorkshopWorkshop materials:Boshra will demonstrate a boring notebook: https://pluto.land/n/s5k1mhpg……and a cool version of the notebook: https://pluto.land/n/jsryfilqOther notebooks demonstrated are available on Pluto.jl featured notebooksSlides"},{"url":"en/docs/API/","title":"🧩 Pluto public API – Control Pluto","description":"Overview of the public API exposed by the Pluto.jl package.","tags":["docs","internals","advanced","sessionactions","API"],"text":"The Pluto package has a few functions that allow you to programmatically control Pluto. This page contains an overview of the public API exposed by the Pluto.jl package. We have also factored out the packages Malt.jl, ExpressionExplorer.jl and PlutoDependencyExplorer.jl. These packages contain useful functionality that is not documented here.OverviewYou can use ServerSession and SessionActions (module) for opening notebooks, shutting down, reading results and exporting to a file. With run you can serve a web interface of a ServerSession on localhost.The Notebook and Cell structs are used to store notebook state. Their fields are not public API, but they are mostly stable in practice. You can read our tests, like this one to see how to interact with notebooks.There is public API to change bond values programmatically: get_bond_names and set_bond_values_reactive, to trigger reactivity.The functions frontmatter_html and generate_html let you export a notebook to a standalone HTML file. (A PDF file is just a browser print of the HTML file, see PlutoPDF.jl.) See also frontmatter. You can use notebook_to_js to get a ‘statefile’. You can use pack and unpack to access Pluto’s MsgPack implementation. Firebasey contains Pluto’s deep-state diffing algorithm (like immer.js).Pluto contains functions to programmatically manage the package environment contained in a Pluto notebook: reset_notebook_environment, update_notebook_dependencies, activate_notebook_environment and will_use_pluto_pkg.There are some utility functions to work with Pluto notebook file extensions: pluto_file_extensions, without_pluto_file_extension and is_pluto_notebook.SessionActionsThese functions are in the Pluto.SessionActions module. Everything in Pluto.SessionActions is public API, and covered by semver. Available functions are:SessionActions.openSessionActions.open_urlSessionActions.newSessionActions.shutdownSessionActions.moveServerSessionAll functionality in SessionActions requires a Pluto.ServerSession object. You can create a session with the Pluto.ServerSession() constructor:session = Pluto.ServerSession()\nYou can also specify the keyword argument options to change the Configuration. For example:session = Pluto.ServerSession(;\n        options=Pluto.Configuration.from_flat_kwargs(\n            auto_reload_from_file=true,\n            etc...\n        )\n    )\nOpening notebooksOnce you have a ServerSession, you can open notebooks in it. You can use open and open_url.openYou can use open to open a notebook from a local file path, and add it to the session.open(session::ServerSession, path::AbstractString; \n    run_async::Bool=true, \n    as_sample::Bool=false, \n    execution_allowed::Bool=true,\n    notebook_id::UUID=uuid1()\n    clear_frontmatter::Bool=false,\n)\nUseful keyword arguments:execution_allowed: If false, the notebook will launch in “Safe Preview” mode. This is the default behavior when opening notebooks using the Pluto web interface.run_async: If true, the function will block until all cells in the notebook have finished executing. If false, the function will return immediately after starting the notebook, and cells will execute in the background.as_sample: If true, Pluto will not open the path, but create a new temporary copy of the notebook at path and open that instead.clear_frontmatter: If true, any frontmatter in the notebook file will be removed.open_urlYou can use open_url to download a notebook from the web and open it.function open_url(session::ServerSession, url::AbstractString; kwargs...)\nThe same keyword arguments as open are supported.newYou can use new to create a new empty notebook in the session.new(session::ServerSession;\n    run_async=true,\n    notebook_id::UUID=uuid1()\n)\nSee open for the meaning of run_async.More actionsshutdownYou can use shutdown to shut down a session.shutdown(session::ServerSession, notebook::Notebook;\n    keep_in_session::Bool=false,\n    async::Bool=false,\n    verbose::Bool=true\n)\nKeyword arguments:keep_in_session: If false, the notebook will also be removed from session.notebooks.async: If true, the function will return quickly, and the shutdown will happen in the background.verbose: If true, warning messages might be logged.moveYou can use move to change where a notebook is stored.move(session::ServerSession, notebook::Notebook, newpath::String)\nrunUse Pluto.run to start Pluto. This is how most people start Pluto:run(; kwargs...)\nKeyword arguments: check out Configuration.If you created your own ServerSession, you can use run! and run to start the web interface for that session.run(session::ServerSession)\nrun!(session::ServerSession)\nrun! will start the server, and return a RunningPlutoServer once it’s ready. You can Base.wait on it to block until the server stops (with Ctrl+C), or Base.close to shut it down. run is a shorthand for Base.wait ∘ run!.Exporting notebooks Generate the HTML export contents of a notebook:generate_html(notebook::Notebook)::String\nThis includes frontmatter HTML head content, but you can also generate this separately with:frontmatter_html(fm::Dict{String,Any})::String\nfm can be the output of Pluto.frontmatter.StatefileA core part of how Pluto works is its state synchronization (between the Julia server and the connected web browsers). All parties work on a shared “statefile” representation of the notebook. This is a JSON-like structure that contains all information about the notebook (cells, code, outputs, logs, timings, etc). Read more about it in Pluto’s source code, by reading the docstring of Pluto.Firebasey.To get the statefile of a Notebook, use:notebook_to_js(notebook::Notebook)::Dict{String,Any}\nThe output structure is easy to work with in another language (like JavaScript). Its structure is not covered by semver.More info about Pluto's state management (Firebasey docstring)State management in PlutoAka: how do the server and clients stay in sync?A Pluto notebook session has state: with this, we mean:The input and ouput of each cell, the cell order, and more metadata about the notebook and cells [state]This state needs to be synchronised between the server and all clients (we support multiple synchronised clients), and note that:Either side wants to update the state. Generally, a client will update cell inputs, the server will update cell outputs.Both sides want to react to state updatesThe server is in Julia, the clients are in JSThis is built on top of our websocket+msgpack connection, but that doesn't matter too muchWe do this by implementing something similar to how you use Google Firebase: there is one shared state object, any party can mutate it, and it will synchronise to all others automatically. The state object is a nested structure of mutable Dicts, with immutable ints, strings, bools, arrays, etc at the endpoints.Some cool things are:Our system uses object diffing, so only changes to the state are actually tranferred over the network. But you can use it as if the entire state is sent around constantly.In the frontend, the shared state is part of the react state, i.e. shared state updates automatically trigger visual updates.Within the client, state changes take effect instantly, without waiting for a round trip to the server. This means that when you add a cell, it shows up instantly.Diffing is done using immer.js (frontend) and src/webserver/Firebasey.jl (server). We wrote Firebasey ourselves to match immer's functionality, and the cool thing is: it is a Pluto notebook! Since Pluto notebooks are .jl files, we can just include it in our module.The shared state object is generated by notebook_to_js. Take a look! The Julia server orchestrates this firebasey stuff. For this, we keep a copy of the latest state of each client on the server (see current_state_for_clients). When anything changes to the Julia state (e.g. when a cell finished running), we call send_notebook_changes!, which will call notebook_to_js to compute the new desired state object. For each client, we diff the new state to their last known state, and send them the difference.Responding to changes made by a clientWhen a client updates the shared state object, we want the server to react to that change by taking an action. Which action to take depends on which field changes. For example, when state[\"path\"] changes, we should rename the notebook file. When state[\"cell_inputs\"][a_cell_id][\"code\"] changes, we should reparse and analyze that cel, etc. This location of the change, e.g.  \"cell_inputs/<a_cell_id>/code\" is called the path of the change.effects_of_changed_state define these pattern-matchers. We use a Wildcard() to take the place of any key, see Wildcard, and we use the change/update/patch inside the given function.Not everything uses the shared state (yet)Besides :update_notebook, you will find more functions in responses that respond to classic 'client requests', such as :reshow_cell and :shutdown_notebook. Some of these requests get a direct response, like the list of autocomplete options to a :complete request (in src/webserver/REPLTools.jl). On the javascript side, these direct responses can be awaited, because every message has a unique ID.stateTwo other meanings of state could be:The reactivity data: the parsed AST (Expr) of each cell, which variables are defined or referenced by which cells, in what order will cells run?The state of the Julia process: i.e. which variables are defined, which packages are imported, etc.The first two (1 & 2) are stored in a Notebook struct, remembered by the server process (Julia). (In fact, (2) is entirely described by (1), but we store it for performance reasons.) I included (3) for completeness, but it is not stored by us, we hope to control and minimize (3) by keeping track of (1) and (2).pack and unpackYou can use Pluto.pack and Pluto.unpack to serialize and deserialize data (like the statefile) using MsgPack (with a couple of Pluto extensions and optimizations).pack(x::Any)::Vector{UInt8}\nunpack(data::Vector{UInt8})::Any\nFirebaseyFirebasey is Pluto’s deep-state diffing algorithm (like immer.js). It is used to efficiently synchronize notebook state between the Julia server and the web browsers. To see simple examples of Firebasey usage (and its public API), check out the PlutoSliderServer.jl source code.Firebasey is written as a Pluto notebook, and you can open src/webserver/Firebasey.jl in Pluto to see many more examples.BondsYou can use get_bond_names to get the list of variables names that are bound with @bind:get_bond_names(session::ServerSession, notebook::Notebook)::Set{String}\nWith set_bond_values_reactive you can change the values of bound variables to trigger a reactive run in a Notebook. Note that the values should be those before transformation.# set the new values\nnotebook.bonds[:x] = Dict(\"value\" => 1)\nnotebook.bonds[:y] = Dict(\"value\" => \"two\")\n\nset_bond_values_reactive(;\n    session::ServerSession, notebook::Notebook,\n    # names of the bonds that are changed\n    bound_sym_names::AbstractVector{Symbol},\n    # just leave this as default\n    is_first_values::AbstractVector{Bool}=[false for x in bound_sym_names],\n    # if `false`, the function will block until all reactive cells have run\n    run_async::Bool=true,\n)::TopologicalOrder\nPackage managementPluto contains functions to programmatically manage the package environment contained in a Pluto notebook. These functions are:reset_notebook_environmentreset_notebook_environment(notebook_path::String; keep_project::Bool=false, backup::Bool=true)Remove the embedded Project.toml and Manifest.toml from a notebook file, modifying the notebook file. If keep_project is true, only Manifest.toml will be deleted. A backup of the notebook file is created by default.update_notebook_environmentupdate_notebook_environment(notebook_path::String; backup::Bool=true, level::Pkg.UpgradeLevel=Pkg.UPLEVEL_MAJOR)Call Pkg.update in the package environment embedded in a notebook file, modifying the notebook file. A Pkg.UpgradeLevel can be passed to the level keyword argument. A backup file is created by default. activate_notebook_environmentactivate_notebook_environment(notebook_path::String; show_help::Bool=true)::NothingActivate the package environment embedded in a notebook file, for interactive use. This will allow you to use the Pkg REPL and Pkg commands to modify the environment, and any changes you make will be automatically saved in the notebook file.More help will be displayed if show_help is true.Limitations:Shut down the notebook before using this functionality.Non-interactive use is limited, use the functional form instead, or insert sleep calls after modifying the environment.InfoThis functionality works using file watching. A dummy repository contains a copy of the embedded tomls and gets activated, and the notebook file is updated when the dummy repository changes.activate_notebook_environment(f::Function, notebook_path::String)Temporarily activate the package environment embedded in a notebook file, for use inside scripts. Inside your function f, you can use Pkg commands to modify the environment, and any changes you make will be automatically saved in the notebook file after your function finishes. Not thread-safe.This method is best for scripts that update notebook files. For interactive use, the method activate_notebook_environment(notebook_path::String) is recommended.ExamplePluto.activate_notebook_environment(\"notebook.jl\") do\n    Pkg.add(\"Example\")\nend\n#-> Now the file \"notebook.jl\" was updated!WarningThis function uses the private method Pkg.activate(f::Function, path::String). This API might not be available in future Julia versions. 🤷will_use_pluto_pkgwill_use_pluto_pkg(notebook_path::String)::BoolWill this notebook use the Pluto package manager? false means that the notebook contains Pkg.activate or another deactivator.File extensions Pluto notebook files are usually .jl, but there are some other “official” extensions like .plutojl, .pluto.jl and more. There are some utility functions:# List of \"official\" Pluto file extensions\npluto_file_extensions::Vector{String}\n\n# Remove Pluto file extension from path\nwithout_pluto_file_extension(path::String)::String\n\n## Does the path end with a pluto file extension (like `.jl` or `.pluto.jl`) and does the first line say `### A Pluto.jl notebook ###`?\nis_pluto_notebook(path::String)::Bool"},{"url":"en/docs/AbstractPlutoDingetjes/","title":"AbstractPlutoDingetjes.jl – develop enhanced Pluto widgets","description":"AbstractPlutoDingetjes allows you to write more advanced widgets to be used inside Pluto.jl.","tags":["docs","widgets","AbstractPlutoDingetjes","advanced"],"text":" A Pluto.jl notebook v0.20.25 frontmatter image \"https media.giphy.com media l3vRfDn9ca5PVkHv2 giphy.gif\" title \"AbstractPlutoDingetjes.jl – develop enhanced Pluto widgets\" layout \"layout.jlhtml\" tags \"docs\", \"widgets\", \"AbstractPlutoDingetjes\", \"advanced\" date \"2023 11 21\" description \"AbstractPlutoDingetjes allows you to write more advanced widgets to be used inside Pluto.jl.\" license \"Unlicense\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils using AbstractPlutoDingetjes md\"\"\" AbstractPlutoDingetjes.jl If you want to design widgets to be used inside Pluto.jl like PlutoUI components, a plotting package, etc , AbstractPlutoDingetjes lets you hook into more advanced Pluto features. This package works best in combination with HypertextLiteral.jl https github.com JuliaPluto HypertextLiteral.jl . If you don't know about HypertextLiteral.jl yet, you should check out the overview of Pluto widgets https plutojl.org en docs advanced widgets first. \"\"\" Docs.Binding AbstractPlutoDingetjes, AbstractPlutoDingetjes md\"\"\" https media.giphy.com media l3vRfDn9ca5PVkHv2 giphy.gif \"\"\" md\"\"\" AbstractPlutoDingetjes.Bonds \"\"\" Docs.Binding AbstractPlutoDingetjes.Bonds, initial value Docs.Binding AbstractPlutoDingetjes.Bonds, transform value Docs.Binding AbstractPlutoDingetjes.Bonds, possible values Docs.Binding AbstractPlutoDingetjes.Bonds, NotGiven Docs.Binding AbstractPlutoDingetjes.Bonds, InfinitePossibilities Docs.Binding AbstractPlutoDingetjes.Bonds, validate value md\"\"\" AbstractPlutoDingetjes.Display \"\"\" Docs.Binding AbstractPlutoDingetjes.Display, published to js Docs.Binding AbstractPlutoDingetjes.Display, with js link Docs.Binding AbstractPlutoDingetjes.Display, Symbol \" embed\" Docs.Binding AbstractPlutoDingetjes.Display, Symbol \" auto id\" Docs.Binding AbstractPlutoDingetjes.Display, ReactDOMElement md\"\"\" Extras \"\"\" Docs.Binding AbstractPlutoDingetjes, is supported by display Docs.Binding AbstractPlutoDingetjes, is inside pluto import PlutoUI PlutoUI.TableOfContents include definitions true pkgversion AbstractPlutoDingetjes "},{"url":"en/docs/ExpressionExplorer/","title":"ExpressionExplorer.jl – documentation ","description":"Find all variables referenced and assigned in a Julia expression. Used internally by Pluto.jl.","tags":["docs","internals","reactivity","advanced","ExpressionExplorer"],"text":" A Pluto.jl notebook v0.19.41 frontmatter image \"https media.giphy.com media 242BaXJnCfe7hOVrsE giphy.gif\" title \"ExpressionExplorer.jl – documentation \" layout \"layout.jlhtml\" order 70 license \"MIT\" description \"Find all variables referenced and assigned in a Julia expression. Used internally by Pluto.jl.\" tags \"docs\", \"internals\", \"reactivity\", \"advanced\", \"ExpressionExplorer\" date \"2023 10 31\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils using PlutoUI TableOfContents using ExpressionExplorer Markdown.parse read joinpath pkgdir ExpressionExplorer , \"README.md\" , String "},{"url":"en/docs/PlutoDependencyExplorer/","title":"PlutoDependencyExplorer.jl – documentation","description":"Given a list of cell codes, PlutoDependencyExplorer can tell you in which order these cells should run. Used internally by Pluto.jl.","tags":["docs","PlutoDependencyExplorer","internals","reactivity","ExpressionExplorer","advanced"],"text":" A Pluto.jl notebook v0.20.3 frontmatter image \"https media.giphy.com media 242BaXJnCfe7hOVrsE giphy.gif\" title \"PlutoDependencyExplorer.jl – documentation\" date \"2024 01 21\" order 80 license \"Unlicense\" description \"Given a list of cell codes, PlutoDependencyExplorer can tell you in which order these cells should run. Used internally by Pluto.jl.\" tags \"docs\", \"PlutoDependencyExplorer\", \"internals\", \"reactivity\", \"ExpressionExplorer\", \"advanced\" layout \"layout.jlhtml\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils using PlutoDependencyExplorer using PlutoUI TableOfContents include definitions true md\"\"\" PlutoDependencyExplorer.jl \"\"\" Docs.Binding PlutoDependencyExplorer, PlutoDependencyExplorer md\"\"\" Basic example Let's define our \"notebook\", which is just a list of cells \"\"\" const PDE PlutoDependencyExplorer struct SimpleCell PDE.AbstractCell code end notebook SimpleCell. \"x y\" \"x 1\" \"y x 2\" md\"\"\" Next, we want to calculate its toplogy , this is the dependency graph of the notebook all links between cells. \"\"\" empty topology PDE.NotebookTopology SimpleCell topology PDE.updated topology empty topology, notebook, notebook get code str c c.code, get code expr c Meta.parse c.code , md\"\"\" info When reading this notebook, you can click on the data structures in the cells above to expand their tree viewer \"\"\" md\"\"\" Now that we have the topology, we can order cells in the topology. \"\"\" order PDE.topological order topology md\"\"\" The result contains an ordered list of the notebook cells \"\"\" order.runnable md\"\"\" You can also ask PlutoDependencyExplorer which cells should run if one cell re runs. This is a recursive search. For example, if I re run the cell that defines `y` \"\"\" notebook 3 PDE.topological order topology, notebook 3 .runnable md\"\"\" By the way, you can also ask PlutoDependencyExplorer which cell defines `y` \"\"\" PDE.where assigned topology, Set y md\"\"\" Core concepts Let's dig deeper into the Basic example above. The first thing we did was define our own subtype of `PlutoDependencyExplorer.AbstractCell`. \"\"\" Docs.Binding PDE, AbstractCell md\"\"\" Next, we calculated the notebook's topology , which stored as a `NotebookTopology`. \"\"\" Docs.Binding PDE, NotebookTopology md\"\"\" We calculated the topology by first creating an empty one, and then updating it with all the cells in our notebook. `NotebookTopology`s are always created by updating a previous one. This is done with `updated topology` \"\"\" Docs.Binding PDE, updated topology md\"\"\" info For the initial topology calculation in our example, we passed `notebook` as `notebook cells`, but also as `updated cells`. This tells `updated topology` that all cells are new. \"\"\" md\"\"\" When the notebook is changed later, you can use `updated topology` to calculate a new topology, which will use the old topology as a cache for cells that were not updated. \"\"\" md\"\"\" More API The following API is public, and covered by our semver vesrion numbering. These functions are used by Pluto and can be used by other packages , but might not be fully documented. We currently don't have the capacity https opencollective.com julialang projects juliapluto to document everything, but you can always take a look at Pluto's source for an example of how these functions are used, or you can contact us. \"\"\" md\" More basics\" Docs.Binding PDE, where assigned Docs.Binding PDE, where referenced Docs.Binding PDE, all cells md\" Disabled & resolved\" Docs.Binding PDE, is disabled Docs.Binding PDE, is resolved Docs.Binding PDE, set unresolved md\" Misc\" Docs.Binding PDE, exclude roots Docs.Binding PDE, is soft edge md\"\"\" PlutoDependencyExplorer defines an additional method for `ExpressionExplorer.external package names` \"\"\" Docs.Binding PDE.ExpressionExplorer, external package names md\" Cell precedence heuristic\" Docs.Binding PDE, cell precedence heuristic Docs.Binding PDE, DEFAULT PRECEDENCE HEURISTIC md\"\"\" Reactivity error types These types are possible value types of the `TopologicalOrder.errable` field. \"\"\" Docs.Binding PDE, ReactivityError Docs.Binding PDE, CyclicReferenceError Docs.Binding PDE, MultipleDefinitionsError md\"\"\" Data structures We defined immutable versions of some core data structures. \"\"\" Docs.Binding PDE, ImmutableDefaultDict Docs.Binding PDE, ImmutableSet Docs.Binding PDE, ImmutableVector Docs.Binding PDE, setdiffkeys Docs.Binding PDE, delete unsafe md\"\"\" ExpressionExplorerExtras These are some things that are too Pluto specific to go into ExpressionExplorer.jl, but are available through PDE as public API in the submodule `ExpressionExplorerExtras`. \"\"\" const EEE PlutoDependencyExplorer.ExpressionExplorerExtras Docs.Binding EEE, ExpressionExplorerExtras Docs.Binding EEE, can be function wrapped Docs.Binding EEE, can macroexpand Docs.Binding EEE, can macroexpand no bind Docs.Binding EEE, collect implicit usings Docs.Binding EEE, maybe macroexpand pluto Docs.Binding EEE, pretransform pluto pkgversion PlutoDependencyExplorer "},{"url":"en/docs/PlutoHooks/","title":"PlutoHooks","description":"","tags":[],"text":" A Pluto.jl notebook v0.20.23 using Markdown using InteractiveUtils using PlutoHooks Markdown.parse read joinpath pkgdir PlutoHooks , \"README.md\" , String md\"A fuller overview can be found under https juliapluto.github.io PlutoHooks.jl src notebook.html A fuller overview can be found under `https juliapluto.github.io PlutoHooks.jl src notebook.html` \" md\"\"\" Docstrings \"\"\" Docs.Binding PlutoHooks, Symbol \" use deps\" Docs.Binding PlutoHooks, Symbol \" use effect\" Docs.Binding PlutoHooks, Symbol \" use memo\" Docs.Binding PlutoHooks, Symbol \" use state\" Docs.Binding PlutoHooks, Symbol \" use ref\" Docs.Binding PlutoHooks, Symbol \" use is pluto cell\" Docs.Binding PlutoHooks, Symbol \" skip as script\" Docs.Binding PlutoHooks, Symbol \" only as script\" pkgversion PlutoHooks "},{"url":"en/docs/PlutoPages/","title":"🏗️ PlutoPages.jl","description":"How to use PlutoPages.jl to generate static websites from Pluto notebooks.","tags":["docs","publishing","PlutoPages","share","web","static"],"text":"PlutoPages.jl (advanced)PlutoPages.jl is a Static Site Generator designed to work well with Pluto notebooks. It’s a tool that turns a folder of files (Pluto notebook, Markdown files, images, and more) into a complete static website, that you can host using a service like GitHub Pages or Netlify. It is heavily inspired by Eleventy, so you can also read their documentation to understand the concepts better.PlutoPages allows for more complex sites than PlutoSliderServer.jl, since it is a full-fledged static site generator. Compared to Eleventy, it has direct support for Pluto notebooks (and their frontmatter). This means that you can easily build things like the sidebar on the left (which is generated from frontmatter fields title, tags and order).Check out the PlutoPages.jl README to get started.Combination with PlutoSliderServer.jlYou can combine PlutoPages.jl with PlutoSliderServer.jl to add interactivity to your website. The idea is as follows:Set up a PlutoSliderServer.jl instance that runs all notebooks in the src/ folder. Serve it on a domain, like plutosliderserver.my-site.org.Set up PlutoPages.jl to generate a static website from the src/ folder in a GitHub action. Publish the site with GitHub pages or Netlify, e.g. my-site.org.Link the two together using PlutoDeployment.toml: add the line slider_server_url = \"https://plutosliderserver.my-site.org\". Now your website will regenerate, and the PlutoPages.jl output will be set to use the slider server for interactivity.Who uses PlutoPages.jl?PlutoPages is relatively new (2023). It is being used in the following places:This website!The course Computational Thinking at MITThe repository computational-thinking-template"},{"url":"en/docs/PlutoSliderServer/","title":"💫 PlutoSliderServer.jl – Overview","description":"How to use PlutoSliderServer.jl to serve Pluto notebooks interactively on the web.","tags":["docs","publishing","PlutoSliderServer","share","web","interactivity"],"text":"PlutoSliderServer.jlPluto notebooks can be made interactive, using the @bind macro. However, when you export your notebook to a file, the @bind interactions do not work. This is because @bind requires a running Julia process to work. Every time that you move a slider or click a button, a Julia process needs to calculate the new reactive values.So how do you get live interactivity on your website? You could run a public Pluto.jl server that runs the notebook, but this has a couple of problems: when someone edits the notebook, all future visitors will see these updates – it will quickly stop working. That’s not what we want! You could start a new Pluto session for every visitor (like binder), but this means that every visitor needs to wait for the notebook to load, since Julia is quite slow.👉 This is where PlutoSliderServer.jl comes in. It is a web server that runs Pluto notebooks, and it can only calculate changes from @bind updates, code changes are not supported. This, together with some other tricks, means that every visitor gets their own isolated experience, but without the need to start a new Julia process for every visitor.PlutoSliderServer in practicePlutoSliderServer.jl is a web server that serves @bind interactivity for one or multiple Pluto notebooks. The typical setup is:You have a GitHub repository with your Pluto notebooks.You rent a Linux server from a provider (like hetzner, digitalocean, gcp, aws, etc.), from your university (SURF Research Cloud in Netherland), or you have a computer that you can leave running. (It is important that this is a isolated environment, without personal data. PlutoSliderServer.jl is not designed to be secure, and you should assume that visitors can execute code on your server.)You set up PlutoSliderServer.jl using our guide, with auto-git watching enabled.Now, you have a website with your notebooks, and all @bind interactivity will work. When you push changess to the notebooks in your GitHub repository, the website will automatically update.Try it outIt is easy to try out PlutoSliderServer.jl on your own computer. If you have a notebook file ready, just run:import PlutoSliderServer\n\n# fill in your own notebook path here!\npath_to_notebook = download(\"https://raw.githubusercontent.com/JuliaPluto/featured/50205f3/src/basic/turtles-art.jl\")\n\nPlutoSliderServer.run_notebook(path_to_notebook)\nHow does it work?Take a look at the PlutoSliderServer.jl README or documentation for more details.API referenceIf you want to see the API reference of PlutoSliderServer.jl, check out the API reference documentation.Who uses PlutoSliderServer.jl?PlutoSliderServer is used by various groups and universities since 2020.The Pluto developers use PlutoSliderServer for:The featured notebooks on featured.plutojl.orgThe course BMLIP at TU EindhovenThe course Computational Thinking at MITHelp and supportIf you have any questions, or you want help setting up PlutoSliderServer.jl, please reach out in all the usual Pluto channels! (Julia Discourse, Julia Slack, Julia Zulip, GitHub issues, etc.)."},{"url":"en/docs/PlutoSliderServerAPI/","title":"PlutoSliderServer.jl – API reference","description":"","tags":["docs","advanced","internals","PlutoSliderServer"],"text":" A Pluto.jl notebook v0.20.24 frontmatter order \"10\" title \"PlutoSliderServer.jl – API reference\" date \"2026 03 13\" tags \"docs\", \"advanced\", \"internals\", \"PlutoSliderServer\" layout \"layout.jlhtml\" license \"Unlicense\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils using PlutoSliderServer using PlutoUI md\"\"\" PlutoSliderServer.jl This page gives a reference of the public API of PlutoSliderServer.jl. To learn more about this package, check out the overview https plutojl.org en docs plutosliderserver and the repository https github.com JuliaPluto PlutoSliderServer.jl . \"\"\" md\"\"\" info This is the API reference of the PlutoSliderServer.jl package. Do you want to read an overview instead https plutojl.org en docs plutosliderserver ? \"\"\" PlutoUI.TableOfContents include definitions true md\"\"\" Public API \"\"\" Docs.Binding PlutoSliderServer, run directory Docs.Binding PlutoSliderServer, export directory Docs.Binding PlutoSliderServer, run git directory Docs.Binding PlutoSliderServer, github action Docs.Binding PlutoSliderServer, export notebook Docs.Binding PlutoSliderServer, run notebook Docs.Binding PlutoSliderServer, find notebook files recursive md\"\"\" Helper Functions \"\"\" Docs.Binding PlutoSliderServer, cache filename Docs.Binding PlutoSliderServer, plutohash Docs.Binding PlutoSliderServer, base64urlencode Docs.Binding PlutoSliderServer, base64urldecode md\"\"\" Example `PlutoDeployment.toml` file Here is the full list of options that can be provided in the `PlutoDeployment.toml` file. This is the output of running `PlutoSliderServer.show sample config toml file `. \"\"\" Markdown.MD Markdown.Code \"julia\", string PlutoSliderServer.show sample config toml file "},{"url":"en/docs/accessibility/","title":"✋ Accessibility","description":"Accessibility features of Pluto","tags":["docs","accessibility","screen reader","keyboard navigation","WCAG","navigation"],"text":"Accessibility FeaturesPluto is designed with accessibility in mind. We follow web accessibility standards (WCAG 2.2 Level AA) and continuously work to improve the experience for everyone. If you find any accessibility issues, please get in touch!Here is an overview of the accessibility features of Pluto.Keyboard Navigation and ShortcutsPluto is fully usable without a mouse. You can navigate and control everything using only your keyboard.Keyboard shortcutsYou can execute cells, navigate between cells, and access common functions quickly using shortcuts. You can find a list of all our shortcuts here.Tab navigationPluto’s interface is designed to be keyboard accessible similar to a web page. You can move through all interactive elements on the page using the Tab key.⚠️ Tab navigation in cellsA special note about tab navigation inside cells: when focused inside a cell code editor, the TAB key will indent code instead of navigating. To navigate, you press Esc and then Tab.This video shows an example:You can find a fuller overview of the keyboard shortcuts and between-cell navigation herePluto also supports touch-only use with your device’s on-screen keyboard (OSK): the virtual keyboard that appears on your screen when you tap a text field on tablets, touchscreen laptops, or any device without a physical keyboard.Visual AccessibilityHigh Contrast TextWe design almost everything with enough visual contrast in light and dark mode. Our design goal is that all text meets WCAG 2.2 Level AA contrast standards (minimum ratio of 4.5:1). This improves readability for users with low vision or color blindness.Dark Mode SupportPluto automatically follows your operating system or browser’s light/dark mode preference. Dark mode can reduce eye strain.Font Size and ZoomIf you want to use a larger font size, you can use your browser’s zoom function (Ctrl/Cmd + ±) to adjust the size of Pluto’s interface. Pluto is designed to scale well, and it also works in very high zoom levels. The layout will adapt to the available screen size.Reduced MotionPluto respects the prefers-reduced-motion CSS setting. If you’ve enabled “Reduce motion” or “Prefers reduced motion” in your browser or OS accessibility settings, then Pluto will minimize animations. This helps users with motion sensitivity.Screen Reader SupportPluto uses semantic HTML and ARIA (Accessible Rich Internet Applications) labels to work with screen readers (like JAWS, NVDA, VoiceOver, TalkBack, and Narrator). We follow WAI-ARIA best practices to ensure interactive elements are properly announced and navigable.Screen reader support is available, but not perfect yet. We need more user feedback to continue improving. The current experience is as follows:HTML exports from Pluto are believed to be screen reader friendly, as long as the notebook author also takes care to produce accessible content.Live notebook editing has basic screen reader support, including announcing (aria-live: polite) reactive changes to cell output. All interface UI has ARIA labels and is keyboard navigable.We need your feedback! If you use a screen reader with Pluto, please share your experience - what works well and what could be better. Your input is essential for helping us prioritize improvements. See this issue to join the conversation or use our feedback tool to report accessibility barriers.LanguageWe try to use simple language in the Pluto interface and in our documentation.Pluto is available in multiple languages, making it accessible to non-English speakers. Pluto can be used in Left-to-Right and Right-to-Left text layouts (both interface and content). You can read more about language support here. Our documentation is currently only available in English.HTML export from Pluto are designed to be machine-translation-friendly. This means using lang and translate attributes in the HTML. You can also use machine translation while editing a notebook.And more?Found an accessibility issue? Let us know through our feedback tool or community channels!"},{"url":"en/docs/advanced-widgets/","title":"Advanced widgets – overview","description":"Pluto provides a framework for advanced input and display widgets.","tags":["docs","advanced","widgets","AbstractPlutoDingetjes","JavaScript"],"text":" A Pluto.jl notebook v1.0.0 frontmatter image \"https github.com JuliaPluto Pluto.jl assets 6933510 0a27e62f 6ef1 4f13 b47c 2a2cefa8850a\" order \"0\" title \"Advanced widgets – overview\" date \"2024 04 22\" tags \"docs\", \"advanced\", \"widgets\", \"AbstractPlutoDingetjes\", \"JavaScript\" description \"Pluto provides a framework for advanced input and display widgets.\" layout \"layout.jlhtml\" license \"Unlicense\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils This Pluto notebook uses bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of bind gives bound variables a default value instead of an error . macro bind def, element format off return quote local iv try Base.loaded modules Base.PkgId Base.UUID \"6e696c72 6542 2067 7265 42206c756150\" , \"AbstractPlutoDingetjes\" .Bonds.initial value catch b missing end local el esc element global esc def Core.applicable Base.get, el ? Base.get el iv el el end format on end begin import Pkg pde joinpath pwd , \"..\", \"..\", \"..\", \"pluto deployment environment\" if isdir pde Pkg.activate pde, io devnull Pkg.instantiate io devnull else warn \"Notebook launched outside of plutojl.org website repository... Installing packages from registry.\" Pkg.activate temp true Pkg.add \"HypertextLiteral\", \"AbstractPlutoDingetjes\", \"PlutoUI\" end import AbstractPlutoDingetjes using HypertextLiteral, PlutoUI Text \"Packages loaded\" end md\"\"\" Developing advanced widgets for Pluto Pluto has a number of advanced features for developers who want to create complex widgets for Pluto. Let's define some categories Custom inputs widgets that are used with ` bind`, like a slider or a map location picker. Custom outputs for visualising results, like a plot or a map with labels. Pluto provides lots of API that lets you write your own widgets, using a high level of integration into the Pluto engine. You can easily add Pluto specific widgets to an existing package without adding a Pluto dependency , or write a new package. PlutoUI.jl https featured.plutojl.org basic plutoui.jl is also built using this API. A quick list of things that our API offers You can use HypertextLiteral.jl https github.com JuliaPluto HypertextLiteral.jl or similar to create dynamic HTML output that reacts to data. We have a JavaScript execution engine https plutojl.org en docs javascript api , and you can send large amounts of data https plutojl.org en docs abstractplutodingetjes published to js like `Vector Float64 ` directly to your visualization with minimal overhead. You can also send functions https plutojl.org en docs abstractplutodingetjes with js link , which can be called dynamically from JavaScript. Pluto's display system can be embedded https plutojl.org en docs abstractplutodingetjes embed inside of your app, and you can manipulate Preact's Virtual DOM https plutojl.org en docs abstractplutodingetjes ReactDOMElement from Julia. \"\"\" md\"\"\" warning \"This is an advanced guide\" This document explains how to make new widgets for Pluto. Are you looking for information on getting started with interactivity in Pluto , and how to use ` bind`? Then take a look at the ` bind` documentation .. bind instead. \"\"\" TableOfContents include definitions true md\"\"\" Custom input PlutoUI.jl provides some basic inputs, like sliders, textfields and more. But you can also make your own specialised widget For example, you could make screenshot of a map location picker https github.com lukavdplas PlutoMapPicker.jl raw main screenshot.png A map location picker https github.com lukavdplas PlutoMapPicker.jl , showing a map, and giving back the clicked coordinate with ` bind`. screenshot of a chemical equation builder https github.com JuliaPluto Pluto.jl assets 6933510 0a27e62f 6ef1 4f13 b47c 2a2cefa8850a A chemical equation builder https youtu.be lNbU5jNp67s?t 1546 , giving back a `Catalyst.ReactionSystem` with ` bind`. screenshot of a composed widget https user images.githubusercontent.com 6933510 145588612 14824654 5c73 45f8 983c 8913c7101a78.png A widget composed with Markdown and PlutoUI, giving back 4 values in a tuple with ` bind`. \"\"\" md\"\"\" No JavaScript Composing widgets Some widgets can be written as a combination of existing inputs, and static content like text, styles, layout and images. This means that you can make simple widgets using only Julia and HTML or Markdown, without JavaScript. For this, you can use `PlutoUI.combine` combine `PlutoUI.Experimental.transformed value` transformed value In some cases, you might just want to \"wrap\" and existing widget in static content `PlutoUI.Experimental.wrapped` wrapped Widgets created with these methods can be published in a package \"\"\" md\"\"\" Custom inputs with JavaScript The Pluto developers 💖💖💖 love JavaScript And Pluto also provides a first class framework for writing widgets using JavaScript. Preliminary writing JavaScript Before reading further, make sure that you understand the basics of writing JavaScript inside Pluto, and that you know how to debug the web using the DevTools of your favourite browser. To learn more, take a look at the featured notebooks https featured.plutojl.org about \"Pluto and the Web\", and read the documentation about our JavaScript API https plutojl.org en docs javascript api . Preliminary `type show htl` Here is the core recipe to use when writing your own widgets 1. Define a type 2. Define a `Base.show` method for HTML 3. Use `HypertextLiteral. htl` to write your widget, using the `io` from `show`. This should be the minimal template for every widget that you write. ```julia import HypertextLiteral htl begin struct MyCoolSlider min Real max Real end function Base.show io IO, m MIME\"text html\", d MyCoolSlider show io, m, htl \"\\\"\" input type range min d.min max d.max \"\"\\\" end end ``` ```julia use it like so bind value MyCoolSlider 5, 10 ``` Let's see it in action \"\"\" import HypertextLiteral htl begin struct MyCoolSlider min Real max Real end function Base.show io IO, m MIME\"text html\", d MyCoolSlider show io, m, htl \"\"\" input type range min d.min max d.max \"\"\" end end bind value MyCoolSlider 5, 10 value md\"\"\" It works Pluto renders your widget by calling the `Base.show` method, and displaying that in the page , it then finds the first element ` input ... ` . Pluto adds an event listener to the `\"input\"` event, and when fired or when first rendered , Pluto takes the `.value` property, sends it to Julia, and it becomes your bound variable. \"\"\" md\"\"\" Core concepts `currentScript`, `value`, input event The widget above `MyCoolSlider` works because the `input` element fires an `\"input\"` event when moved, and it has a `.value` property. This is true for all the built in ` input ... ` elements https developer.mozilla.org en US docs Web HTML Element input . Now... when writing your own inputs, you need to fake it Set the `.value` property from JavaScript, and fire an `\"input\"` event. To select the element, `currentScript` is special API added by Pluto, it refers to the ` script ` element that your code is written in. In the example below, our custom input element is a wrapper ` div `, and we use JavaScript to select it with `currentScript.parentElement`, to set its `value` and to fire the `\"input\"` event. 👉 Can you find this in the code? \"\"\" begin struct RectangleDrawing end function Base.show io IO, m MIME\"text html\", rd RectangleDrawing Base.show io, m, htl \"\"\" div canvas width \"200\" height \"200\" style \"position relative\" canvas script 🐸 `currentScript` is the current script tag we use it to select elements 🐸 const div currentScript.parentElement const canvas div.querySelector \"canvas\" const ctx canvas.getContext \"2d\" var startX 80 var startY 40 function onmove e 🐸 We send the value back to Julia 🐸 div.value e.layerX startX, e.layerY startY div.dispatchEvent new CustomEvent \"input\" ctx.fillStyle ' ffecec' ctx.fillRect 0, 0, 200, 200 ctx.fillStyle ' 3f3d6d' ctx.fillRect startX, startY, ...div.value canvas.onpointerdown e startX e.layerX startY e.layerY canvas.onpointermove onmove canvas.onpointerup e canvas.onpointermove null Fire a fake pointermoveevent to show something onmove layerX 130, layerY 160 script div \"\"\" end end md\"\"\" Try dragging a rectangle in the box below \"\"\" bind dims RectangleDrawing dims md\"\"\" Custom output Pluto can be used as a framework to have high quality widgets powered by JavaScript, displaying data and calculations from Julia. By creating a Custom output , you can wrap your JavaScript powered widget into a Julia function, such as `plot data `. Techniques used to power Custom Outputs can also be used in Custom Inputs A Custom Input is just a Custom Output with added ` bind` support. \"\"\" md\"\"\" Core principle a visualiser function TODO \"\"\" md\"\"\" Julia only Layout You can use `PlutoUI.ExperimentalLayout` to display objects in columns, grids, and more. This lets you put plots next to sliders, text and more. \"\"\" PlutoUI.ExperimentalLayout.grid md\" Layout demo \" Text \"\" Text \"I'm on the left\" Dict a 1, b 2,3 md\"\"\" Combining bonds and outputs When you want to put a bond and an output in the same cell like a slider next to a plot , you need to take special care. You need to define the bond in a separate cell , like so \"\"\" bond bind val Slider 1 20 PlutoUI.ExperimentalLayout.hbox bond, collect 1 val md\"\"\" Special features Using `PlutoUI.ExperimentalLayout` has some special advantages over using ` htl` or another HMTL based method to create layout Pluto treats each item as its own display. So a 2x2 `grid` will act like 4 individual Pluto cells arranged in a grid. In particular, if some of the items in a layout change, then only those items will be re rendered. Items that stayed the same will be unaffected. For bonds, this means that they will not re render and get reset to their initial value. When using HTML and JavaScript, this means that if your `Base.show` method returns exactly the same value, the re render will not be trigger, and ` script `s don't execute again. \"\"\" md\"\"\" HTML HypertextLiteral and alternatives You can achieve the best results when using HTML, CSS and JavaScript to power your widgets. This gives you full control over appearance and behaviour. To use HTML inside a `Base.show` function, we highly recommend ` htl` from HypertextLiteral.jl https github.com JuliaPluto HypertextLiteral.jl , a package developed in collaboration with the Pluto developers, but also useful outside of Pluto. It's a small dependency, and it gives optimal performance. Another option is HyperScript.jl https github.com JuliaWeb Hyperscript.jl , which provides a \"Julia API to HTML\", whereas HypertextLiteral is closer to HTML itself. You could also use no package, and use `write io, \" div ...\" ` calls to output HTML without a package. For small widgets this will work well, but we would recommend starting with HypertextLiteral give more flexibility later, with little cost. \"\"\" function emoji list xs Vector Integer htl \"\"\" ol htl \" li repeat \"🌸\",x li \" for x in xs ol \"\"\" end emoji list 5,10,3,2,1 html\"\"\" a href \"https github.com JuliaPluto HypertextLiteral.jl\" class \"arrow\" Learn more HypertextLiteral.jl a \"\"\" md\"\"\" JavaScript API ` script ` tags included in HTML output will be executed by Pluto, and you can use this to make interactive and dynamic widgets In your code, you will mostly be using Web APIs your code runs directly in the browser , like DOM manipulation. Use javascript.info https javascript.info or MDN https developer.mozilla.org to learn more about Web APIs. You can also import JavaScript libraries and frameworks and use them in your widget. We think the Web APIs and modern JavaScript are very powerful, and you should be able to do anything you want However, we decided to add a small amount of extra functionality to make it easier to write code specifically for Pluto outputs. \"\"\" html\"\"\" a href \"https plutojl.org en docs javascript api \" class \"arrow\" Learn more JavaScript API a \"\"\" md\"\"\" `AbstractPlutoDingetjes.jl` We recommend reading the docs of `AbstractPlutoDingetjes` https plutojl.org en docs abstractplutodingetjes , containing special API that we offer on top of the Web platform. In particular, I want to highlight two functions for special data needs Use `AbstractPlutoDingetjes.Display.published to js` when visualising a large amount of data using JavaScript, and just interpolating the data into a ` script ` in an `HypertextLiteral. htl` expression is not performant enough. ```julia HypertextLiteral. htl \"\"\\\" script the standard way, fast for small amounts of data let x \\ my vector this is faster for large data let y \\ AbstractPlutoDingetjes.Display.published to js my big vector script \"\\\"\" ``` \"\"\" md\"\"\" Use `AbstractPlutoDingetjes.Display.with js link` when you want to make on demand requests to Julia from your JavaScript code. \"\"\" md\"\"\" If you create a widget with HTML JS for multiple environments VS Code, Jupyter, Documenter, Franklin, Bonito, Genie, etc , it can be useful to check whether the widget is being displayed in Pluto or not. We recommend performing this check inside the `Base.show io IO, m MIME\"text html\", ... ` method, using like `is inside pluto io IO ` to check for Pluto, or `is supported by display` to check for a specific Pluto feature. \"\"\" html\"\"\" a href \"https plutojl.org en docs abstractplutodingetjes \" class \"arrow\" Find more in the AbstractPlutoDingetjes docs a \"\"\" HiddenDocs mod, name details htl \"Show docstring for code name code \" , htl \"\"\" div class \"pluto docs binding\" span id \" name \" name span Base.Docs.doc Base.Docs.Binding mod, name div \"\"\" HiddenDocs PlutoUI, combine HiddenDocs PlutoUI.Experimental, transformed value HiddenDocs PlutoUI.Experimental, wrapped HiddenDocs AbstractPlutoDingetjes.Display, published to js HiddenDocs AbstractPlutoDingetjes.Display, with js link HiddenDocs AbstractPlutoDingetjes, is inside pluto HiddenDocs AbstractPlutoDingetjes, is supported by display HiddenDocs AbstractPlutoDingetjes.Display, Symbol \" embed\" md\"\"\" Distributing widgets Once you created a cool widget, the most user friendly way to distribute it is to publish it in a package . You can create a new package with your widget, or you can add it to an existing package. Dependencies When distributing a widget in a package ExampleWidget.jl , you do not need to add Pluto.jl as a dependency to your Project.toml. You just need to add the packages that you used. This could be HypertextLiteral.jl or AbstractPlutoDingetjes.jl. If you used `combine` or another PlutoUI feature, you add PlutoUI.jl as a dependency. HypertextLiteral.jl and especially AbstractPlutoDingetjes.jl are very small dependencies and will not add any noticeable lag to your package installation. Code in notebook or Julia file? When prototyping your widget, you probably want to work fully inside a notebook. Tip when editing the notebook, copy the `localhost` URL and open it in a second window. That way you can see the code and widget side by side. Once you're done, you have two options for moving it to a package. First, you could store your notebook file directly in the package source code. Use the \"Disable in File\" feature to disable cells where you test your widget. https github.com JuliaPluto AbstractPlutoDingetjes.jl assets 6933510 f96980ff 83ce 4b15 8897 dc3e3b1ba72e Second, you could move your code to a classic `.jl` file. Then you could use Revise.jl or ` revise` from PlutoLinks.jl https github.com JuliaPluto PlutoLinks.jl to test it in a notebook while developing the widget. This option might be nicer if your widget has a lot of JavaScript code. Publishing small packages? If you just created one cool widget, you might think \"I want to publish this, but it's too small for a package \". Here is a little political message from fons do it anyways Life is too short to not publish small packages If you made something fun or valuable, you totally deserve to publish it and share it with others. 💛 It's really valuable for others, and a cool experience for you Publishing a widget in a small package is really valuable Others can use it by simply typing `import ExampleWidget` in a notebook . Without publishing it on General, users need to download scripts, copy code, ... This creates lots of hard to reproduce notebooks Once it's on the registry, it's easier for people to discover Especially if the name starts with `Pluto`, like PlutoMapPicker.jl. People searching for your widget can find it online, because registered package show up on juliahub.com and more. It's easy to get feedback, bug reports and contributions from users. And you can easily make patches and release them to your users. Or maybe it was right from the start, and you don't need this \"\"\" demo img let url \"https user images.githubusercontent.com 6933510 116753174 fa40ab80 aa06 11eb 94d7 88f4171970b2.jpeg\" data read download url PlutoUI.Show MIME\"image jpg\" , data end demo html htl \" b style 'font family cursive ' Hello b \" "},{"url":"en/docs/ai-editor-features/","title":"✨ AI features","description":"Fix syntax errors with one click!","tags":["docs","editor"],"text":"AI editor featuresWe live in wild times! We are still discovering the impact of AI on education and the world. With Pluto, we want to offer modest, helpful AI features that still leave autonomy and creativity with the user (student). Pluto is not a “vibe coding” tool, for better or worse.Automatic syntax fixesPluto can help you fix syntax errors automatically! If you make a typo or your code doesn’t parse, Pluto will offer a button to fix it for you automatically, powered by a cloud AI model.Impact for studentsNote that his feature only fix syntax parse errors, not runtime errors (like MethodError, exceptions, etc). Our view is that syntax errors are just frustrating, and it’s preventing students from having a more valuable learning experience with other topics. The feature still shows what it does, so students get a chance to review the fix and learn from it if they want to.🚨 Experimental! This feature is available in Pluto v0.20.8 and above. See the announcement PR for more details.How to use itWhen you hit a syntax error (e.g. missing end, typo in a function name), Pluto shows a button: “Fix with AI”.Click the button, and you’ll see a prompt explaining what will happen, and you can choose whether you want to use the service.If you accept, Pluto will use a cloud AI model (currently Claude 3.5 haiku) to fix the error, and the cell will be updated with the new code.PrivacyThe first time that you use the feature, Pluto will show a message explaining the current privacy policy of the feature. This might change over time, so check Pluto for the current information. (If the privacy policy changes in the future, you will be asked to accept the new policy.)The feature currently works without sign-in: you can use the feature directly in Pluto without creating an account.FeedbackDoes this not work for you? Or do you have other feedback? Use the built-in feedback form in Pluto, or let us know on GitHub.(beta) AI Prompt generationWe notice that people often use Pluto side-by-side with other AI chat systems, like chatgpt.com or claude.ai. This feature will make that workflow more effective.There is a button to generate a prompt about a cell with context from your notebook. When you ask a question like “What does this code do?” or “Help me add a linear trendline”, it helps to tell the AI model not just the code, but also code from other cells, packages, current output, etc. The prompt generation will automatically add the relevant context to the prompt, so you can get better answers from AI models.Impact for studentsNote that his feature does not use LLMs, it only helps you generate a good prompt for an LLM if you might already use it. The hope is to improve interactions that students have with LLMs, so that they get more accurate responses, instead of getting thrown off by a bad response.Here is a video of the feature in action:🚨 Experimental! This feature is available in Pluto v0.20.9 and above, and is currently in beta. See the announcement PR for more details.How to use itIn any cell in your notebook, click the cell context menu in the top right of the cell TODO ICON, and click “Ask AI”. This will open the prompt generation UI.Now you see the prompt generation UI. If you want, you can type a question that is added to the prompt. When you press Enter or click the “Copy” button, the prompt is copied to your clipboard. You can paste it into an AI chat on another website, like chatgpt.com or claude.ai.How does it work?The prompt is auto-generated based on notebook context. Pluto uses cell inputs, some cell outputs, package information and the reactive dependency graph to generate a prompt. The important feature is that the reactive dependency graph is used to determine which cells are relevant to the current cell.The prompt contains XML tags like <pluto-ai-context-current-cell>. These tags are completely made up, but they help AI models understand the structure of the generated prompt.Try it out on a complicated notebook, and take a look at the generated prompt.Token limitMost AI chat systems have a token limit, which limits the length of the prompt. Pluto will try to generate the best possible prompt that fits within a fixed token limit (currently 3000 tokens). If the token limit is reached, less context will be provided.PrivacyThis feature does not use any LLMs or other web services, it just generates a prompt that you can use as you wish.FeedbackDoes this not work for you? Or do you have other feedback? Use the built-in feedback form in Pluto, or let us know on GitHub.ConfigurationYou can enable or disable Pluto’s AI features with the enable_ai_editor_features setting. To turn off all features, set it to false:Pluto.run(enable_ai_editor_features=false)\nChatGPT block detectionSome AI features will be disabled automatically if Pluto detects that ChatGPT is blocked on your network.This is for universities/workplaces that don’t allow LLM tools as a policy. If this university has already blocked the chat.openai.com (ChatGPT) domain, then Pluto will “go with the flow” and also not offer the AI service. (We check ChatGPT regardless of which LLM is used by Pluto.)More infoBlocking AI features in your courseAre you a teacher who wants to block AI features in your course? You have the following options:Ask your students to start Pluto with Pluto.run(enable_ai_editor_features=false).Ask the system administrator to block ChatGPT: chat.openai.comDoes this not work for you? Or do you have other feedback? Let us know on GitHub, or send Fons an email!"},{"url":"en/docs/architecture/","title":"🔬 Architecture – How does Pluto work?","description":"An overview of the internals of Pluto.jl.","tags":["docs","internals","advanced","architecture"],"text":"How does Pluto work?Pluto.jl is written in JavaScript (frontend) and Julia (backend). The frontend is the app that runs in your web browser where you type code, see outputs, etc. The backend is the Julia program that runs in your terminal with an HTTP server (to serve the frontend and communicate with it), code analysis, reactivity and code execution. The backend runs a Julia process per notebook where user code runs.Before diving into the frontend and backend, let’s look at how they work together.Frontend ↔ BackendAka: how do the server and clients stay in sync?(thank you Michiel for the idea, design and implementation!)A Pluto notebook session has state: with this, we mean: cell code, cell results, status and intermediate progress (eg logs), cell order, package information.This state needs to be synchronised between the server and all clients (we support multiple synchronised clients), and note that:All sides want to update the state. Generally, a client will update cell inputs, the server will update cell outputs.Both sides want to react to state updatesThe server is in Julia, the clients are in JSThis is built on top of our websocket+msgpack connection, but that doesn’t matter too muchWe do this by implementing something similar to how you use Google Firebase: there is one shared state object, any party can mutate it, and it will synchronise to all others automatically. The state object is a nested structure of mutable Dicts, with immutable ints, strings, bools, arrays, etc at the endpoints.Some cool things are:Our system uses object diffing, so only changes to the state are actually tranferred over the network. But you can use it as if the entire state is sent around constantly.In the frontend, the shared state is part of the react state, i.e. shared state updates automatically trigger visual updates.Within the client, state changes take effect instantly, without waiting for a round trip to the server. This means that when you add a cell, it shows up instantly.Diffing is done using immer.js (frontend) and src/webserver/Firebasey.jl (server). We wrote Firebasey ourselves to match immer’s functionality, and the cool thing is: it is a Pluto notebook! Since Pluto notebooks are .jl files, we can just include it in our module.The shared state object is generated by notebook_to_js in src/webserver/Dynamic.jl. Take a look! The Julia server orchestrates this firebasey stuff. For this, we keep a copy of the latest state of each client on the server (see current_state_for_clients). When anything changes to the Julia state (e.g. when a cell finished running), we call send_notebook_changes!, which will call notebook_to_js to compute the new desired state object. For each client, we diff the new state to their last known state, and send them the difference.Responding to changes made by a clientWhen a client updates the shared state object, we want the server to react to that change by taking an action. Which action to take depends on which field changes. For example, when state[\"path\"] changes, we should rename the notebook file. When state[\"cell_inputs\"][a_cell_id][\"code\"] changes, we should reparse and analyze that cel, etc. This location of the change, e.g.  \"cell_inputs/<a_cell_id>/code\" is called the path of the change.effects_of_changed_state define these pattern-matchers. We use a Wildcard() to take the place of any key, see Wildcard, and we use the change/update/patch inside the given function.Not everything uses the shared state (yet)Besides :update_notebook, you will find more functions in responses that respond to classic ‘client requests’, such as :reshow_cell and :shutdown_notebook. Some of these requests get a direct response, like the list of autocomplete options to a :complete request (in src/webserver/REPLTools.jl). On the javascript side, these direct responses can be awaited, because every message has a unique ID.Example: running a cellThe frontend changes the code for cell X in the shared state.The backend receives the changed code and updates its internal representation.The frontend waits for confirmation, and sends a “run cell” command. (This could have been implemented without an explicit “run cell” command.)The backend start a reactive run based on running X. The cell becomes queued, then running, then finished with new results. Every time that something changes, it updates the state of all connected clients.Every time that the backend changes its state, it sends diffs to the frontend, which uses it to update its internal state, which triggers re-rendering of the cells.FrontendThe Pluto app that displays in your web browser (where you type code and see results) is the frontend of Pluto. This application is written in JavaScript (with JSDoc for types), using CodeMirror 6 (code editor platform), preact (variant of React), and immer (state management).Code is in the frontend/ folder.Code structureThe entry point of the app is the frontend/components/Editor.js component – this is the root component. Other components are children here.HintIf you are interested in a specific component in Pluto, you can usually dive right into its code without understanding the whole structure. Tip: search for text that you see (like “Enable and run the cell”), find the i18n key (t_enable_and_run_cell), then search for they key.The Editor component is loaded/rendered by the frontend/editor.js script, which is included in the frontend/editor.html file. When you visit localhost:1234/edit or when you view a notebook online, you are being served this HTML file.State synchronization and actionsMost state is held in the Editor component. This component also contains the notebook state, which is the object shared with the backend.Some of this state is passed down to children, and there are some callbacks being passed down as well. To prevent ‘callback hell’, we have a system called “PlutoActions”, which contains lots of functions to influence the editor state and backend. PlutoActions is available through context. (thank you Panagiotis!)If you are adding a new feature, try to implement it in a way that just requires placing more data in the shared state object in the backend.ReacitivityWe use preact/react as a frontend framework, but this is not the reason why Pluto is reactive. ‘Reactive’ can mean a lot of things, but Pluto’s reacitivity is powered by our own reactivity algorithm in the backend. But: using a framework like React makes it easy to make an interactive app.BundlingOur frontend is buildless, which means that the browser can run our frontend assets (HTML, CSS, JS) directly, without a bundling step. This makes it easy for people to fork and modify Pluto in the normal Julia way. The Pluto server will serve the contents of the frontend/ folder directly, which means that you can edit frontend files, refresh the browser, and see results.But we also have a bundler, which bundles editor.html and index.html. The output of the bundler is in the frontend-dist directory. This directory is gitignored, it only exists if you generate it, and on our official releases. (More on this later.)We bundle for a couple of reasons:Offline support. Our app uses many resources from CDNs (JS packages, typefaces and icons), which are otherwise not available without an internet connection.Reliability. This reduces our dependency on CDNs.Performance. Bundling makes our HTML Export files load faster.Bundler CIThe Julia registry does not allow you to “upload a dist folder” for releases, like in npm. All files to be included in the release need to be on GitHub.Our solution is the .github/workflows/Bundle.yml CI action. For every commit to main, it bundles, and on the dist branch it removes all history, commits the frontend-dist folder (normally gitignored) and pushes. So this branch is always 1 commit ahead of main.When we make a Pluto release, we do it on the dist branch, so that it includes the bundle. TagBot will later git tag the commit, which preserves it forever, even if the dist branch is later overrided.Cell input: CodeMirrorWe make extensive use of CodeMirror 6. Its design aligns very well with our needs, and we are generally impressed by this package. We have implemented many features as CodeMirror extensions. This includes: highlighting globals, Live Docs, autocomplete, package ‘bubbles’ (icon next to using Example), special indenting, and much more. You can find our own extensions in the frontend/components/CellInput folder.The CodeMirror setup is in the the frontend/components/CellInput.js file.For reasons related to CDNs, we have a separate repository where we import and re-export all the API that we need from the different CodeMirror packages: codemirror-pluto-setup.Cell output: displayCell output is implemented in a relatively straightforward way. We have a number of react components, which are matched to the right MIME type. Like a tree data inspector, image display, HTML renderer, plaintext, and some others.The HTML renderer has some special handling of JavaScript, to make it easy to use, and mostly compatible with the Observable Notebook API. You can read more about it here.DesignPluto’s design is homemade, we don’t use a design system or component library. Styles are in vanilla CSS. We use the JuliaMono typeface (thank you Cormullion!).LocalisationPluto is available in 15+ languages, thanks to contributions from the community! You can read more about this in the language documentation.TestingPluto has a puppeteer test suite for end-to-end testing. (thank you Rok for the initial setup!) These tests run a Pluto server, open a browser, and interact with the app like a user would. We run these tests in CI using Chrome.We also have some sanity tests that check that a browser can open and view a notebook. We run these tests in CI using Chrome, Firefox and Safari. .github/workflows/TestFirefox.yml (for all browsers).BackendConfigrationPluto has a configuration system using Configurations.jl. This is a very handy package! (thank you Roger for your work and support!) Nowadays there is also Preferences.jl, but this came too late for our package.Check out the configuration docs to learn more about what can be configured. You can also read more about PlutoSliderServer.jl to see the configuration system in action.HTTP serverPluto runs its own HTTP and WebSocket server on localhost. It serves assets (HTML, CSS, JS, typefaces, SVG, etc) and it has HTTP endpoints for tasks (new notebook, open notebook, etc). After a WebSocket connection is set up, it works with a discrete “messages” system. Messages are encoded with MsgPack.jl. Each message has a type (:current_time) which corresponds to a function on the other side, and some data specific to that message. Messages can be broadcast to all connected frontends, or they can be sent as ‘answer’ to one specific connected client.Very important is the :update_notebook function in the backend (receive patches to the shared state) and its frontend equivalent \"notebook_diff\".Sensitive endpoints of this server are secured with a token, which is generated randomly when you start a server.Process managementPluto runs user code in a separate Julia process. Each notebook gets a Julia process, which is managed using Malt.jl. We wrote Malt ourselves, out of a need for reliable management of Julia processes. (thank you Sergio for your expertise and implementation!) Code for this is in src/evaluation/WorkspaceManager.jl.ReacitivityPluto’s reactivity works using static analysis. Pluto analyzes the expression of each cell to find references and definitions to global variables. Linking these between cells creates a DAG (graph), where cells are nodes and edges are matched reference-definition links.When you run a cell, Pluto will search this DAG to find cells that also need to run.How this works is covered in other documents. Check out the documentation page and the PlutoCon talk by Mikolaj.Macro handlingPluto supports reactive macrocalls and usings. (thank you Paul!) This means that if an expression defines or uses a variable after macroexpansion, Pluto will handle it correctly. This is very difficult to implement, because Pluto now needs to run code to be able to analyze it. The simple flow analyze → run is no longer possible.This is implemented by running reactively in chunks. Pluto will start a reactive run as usual, but whenever a cell has been executed that could give more information (e.g. a new macro was defined, or package loaded), Pluto tries to macroexpand and analyze any remaining cells that still have unknowns. Macroexpansion happens in the notebook process, the resulting expression is sanitzed and returned to the server for analysis.Watch the JuliaCon talk by Paul about this.Package managementPluto has integration with Pkg for:Isolated environment: embedded Project.toml and Manifest.tomlAutomatic package management (adding/removing packages)Version queries (what versions can be installed)The code for this is in src/packages/PkgCompat.jl (all internal Pkg API use is contained here), and Pluto’s package manager is in src/packages/Packages.jl.We have also written a package GracefulPkg.jl that can will try to convert a Manifest.toml between environments with minimal damage.Developing PlutoAre you interested to work on Pluto? Take a look at our developer instructions to get started."},{"url":"en/docs/bind/","title":"🎚️ PlutoUI and @bind","description":"How to use PlutoUI and @bind to have interactive UI like sliders, buttons, and more.","tags":["docs","writing","interactivity","@bind","slider","button","reactivity","widgets"],"text":"Interactivity with @bind and PlutoUIMaking your notebook interactive is very easy with Pluto! This article will teach you how to use @bind to add interactive UI like sliders, buttons, scrubbables, text fields, and more.@bind with PlutoUIThe easiest way to get started is with PlutoUI. Add the following code in your notebook:using PlutoUI\n@bind apples Slider(5:50)\napples\nrepeat(\"🍎\", apples)\nThis is what you get:Global variablesThe core idea with @bind is that you can control a global variable with a UI element. Because Pluto has reactive global variables, it is up to your creativity what you do with it! Anything that depends (indirectly) on the bound variable will automatically update when you change the UI element.Discover more widgets!To see the complete list of UI that PlutoUI provides, including buttons, file upload and layout, check out the PlutoUI documentation! 👇Loading...Read documentation →\n\tconst notebook_html_url = \"https://featured.plutojl.org/basic/plutoui.jl\"\n\tconst white_svg_uri = \"data:image/svg+xml;utf8,<\\svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect width='100%' height='100%' fill='ivory'/><\\/svg>\"\n\n\tfetch(notebook_html_url).then(r => r.text()).catch(e => \"\").then(html_data => {\n\t\tconst doc = new DOMParser().parseFromString(html_data, \"text/html\");\n\t\tconst head = doc.head\n\n\t\tconsole.log({doc, notebook_html_url})\n\t\tconst q = sel => currentScript.parentElement.querySelector(\".pe-card\").querySelector(sel)\n\n\t\tq(\"a img\").src = head.querySelector('meta[property=\"og:image\"]')?.content ??\n\t\t\twhite_svg_uri\n\t\t\n\t\tq(\".pe-about h2\").innerText = (doc.title == \"\" ? null : doc.title) ?? \n\t\t\tnew URL(notebook_html_url).pathname.split(\"/\").map(decodeURIComponent).toReversed().find(s => s) ??\n\t\t\t\"Notebook\"\n\t\t\n\t\tq(\".pe-about p\").innerText = head.querySelector('meta[name=\"description\"]')?.content ?? \n\t\t\t\"\"\n\t})\n\n\n\t.pe-container {\n\t\tcontainer-type: inline-size;\n\t}\n\t\n\t.pe-card {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tmax-width: 700px;\n\n\t\tborder-radius: 6px;\n\t\tbackground: salmon;\n\t\tbackground: linear-gradient(80deg, #e9dbe3, #ffdabe);\n\t\tpadding: 10px;\n\t\tgap: 20px;\n\t\tmargin: 10px 0;\n\t\tbox-shadow: 0 2px 10px rgb(0 0 0 / 14%);\n\t}\n\n\t@container (max-width: 400px) {\n\t\t.pe-card {\n\t\t\tflex-direction: column;\n\t\t\tgap: 0;\n\t\t}\n\t\t.pe-about {\n\t\t\tmargin: 0 10px 10px 10px;\n\t\t}\n\t}\n\n\t.pe-card > a {\n\t\toverflow: hidden;\n\t\tborder-radius: 5px;\n\n\t\tflex: 0 0 35%;\n\t\taspect-ratio: 3 / 2;\n\t}\n\t\n\t.pe-card > a > img {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\t\n\t\tobject-fit: cover;\n\t}\n\n\tdiv.pe-about :is(p, h2) {\n\t\tcolor: black;\n\t\ttext-decoration: none;\n\t\tborder-bottom: none;\n\t\tmargin-block-end: 0;\n\t}\n\n\t.pe-right {\n\t\tflex: 1 1 auto;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: space-between;\n\t}\n\n\t.pe-nav {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.pe-nav a {\n\t\ttext-decoration: none;\n\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Cantarell, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n\t\"Segoe UI Symbol\", system-ui, sans-serif;\n\t\tfont-weight: 700;\n\t\tbackground: white;\n\t\tcolor: black;\n\t\tpadding: 8px 14px;\n\t\tborder-radius: 1000px;\n\t}"},{"url":"en/docs/binder/","title":"🤹 Binder","description":"How to use Binder to run Pluto notebooks in the cloud.","tags":["docs","publishing","binder","share","web","static"],"text":"BinderPluto notebooks can be run in Binder, an awesome service that allows you to run scientific computational notebooks in the cloud. This service is really useful for science accessibility, and for promoting reproducibility.Different from JupyterUsing Binder with Pluto is a bit different from using it with Jupyter and other languages. This is because Binder is designed directly for Jupyter, and it needs some convincing to serve Pluto notebooks instead. The setup is also different – instead of creating a repository on GitHub for your Binder project, we already created one repository for everyone (fonsp/pluto-on-binder), and Binder is built-in to all Pluto notebook exports.Binder for your notebooksThis is really simple! Just create an HTML export of your notebook, that’s it! Each export from Pluto binder functionality built-in, without additional setup.When you view an HTML export from Pluto (like this featured notebook), you will see a button in the top right corner that says “Edit or run”. Clicking this will open a new popup with the options for running the notebook. You can either download the notebook file and run it locally with Pluto, or run the notebook with Binder, directly in your browser.When you share your notebook file (e.g. with pluto.land), this button is also visible, and people can run the notebook with binder.Launch timeWe have created a Binder image that is optimized to launch Pluto as fast as possible. Yet, it can still take a while to run your notebook, because packages from the notebook need to be installed and precompiled. In some cases, the launch may even fail because the precompilation uses too much memory.We think it might be possible to improve this by creating a custom Binder image that is optimized for your notebook, by installing and precompiling the notebook packages during the binder build process, so that they are ready to be loaded when the binder image is launched. If you’re interested in helping us with this, please reach out!Use Binder to try out PlutoYou can also use Binder to try out Pluto.jl. Go to plutojl.org/#try to get started."},{"url":"en/docs/configuration/","title":"⚙️ Configuring Pluto","description":"How to change settings of the Pluto.jl Julia notebook","tags":["docs","editor","configuration"],"text":" A Pluto.jl notebook v0.20.3 frontmatter title \"⚙️ Configuring Pluto\" date \"2025 06 20\" tags \"docs\", \"editor\", \"configuration\" description \"How to change settings of the Pluto.jl Julia notebook\" layout \"layout.jlhtml\" order 99 license \"MIT\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils begin import Pkg pde joinpath pwd , \"..\", \"..\", \"..\", \"pluto deployment environment\" if isdir pde Pkg.activate pde, io devnull Pkg.instantiate io devnull else warn \"Notebook launched outside of plutojl.org website repository... Installing Pluto from registry.\" Pkg.activate temp true Pkg.add \"HypertextLiteral\", \"Pluto\", \"PlutoUI\" end import Pluto, PlutoUI using HypertextLiteral end PlutoUI.TableOfContents include definitions true md\"\"\" Configuring Pluto In Pluto's design, we always try our best to make choices that work best for our audience, rather than adding more settings. We do this to make Pluto less intimidating to use for newcomers, and to avoid situations where issues are caused by a \"wrong configuration\". However, there are some settings intended for system administrators e.g. running a Pluto server for your students , and for advanced Julia users . These settings are mostly about the \"backend\" everything you don't see . We intentionally don't have settings for the \"frontend\" the GUI interface where you type code and see results . Such settings are usually more difficult to implement and maintain. In some cases, we also want to create a homogenous experience a notebook should look the same on different computers. The best configuration We thought long and hard to find the best default configuration. To get the best Pluto experience, don't change these settings . A custom experience You can achieve a lot of customisability by writing special code Take a look at PlutoLinks.jl https github.com JuliaPluto PlutoLinks.jl , PlutoHooks.jl https github.com JuliaPluto PlutoLinks.jl and AbstractPlutoDingetjes.jl https plutojl.org en docs abstractplutodingetjes . You can also use CSS e.g. with HypertextLiteral.jl https github.com JuliaPluto HypertextLiteral.jl to customise the look of a notebook. \"\"\" md\"\"\" How to use settings Option 1 `Pluto.run kwargs... ` The easiest way to configure Pluto is by providing keyword arguments to `Pluto.run`. For example, to configure the port used to run Pluto ```julia Pluto.run port 1235 ``` \"\"\" md\"\"\" Option 2 `Pluto.ServerSession` You can also create a session first, configure it, and then run a server on that session. ```julia session Pluto.ServerSession session.options.server.auto reload from file true session.options.compiler.optimize 0 Pluto.run session ``` \"\"\" htl \"\"\" ul map categories do c htl \" li a href string \" \", c c a li \" end ul \"\"\" begin categories CompilerOptions, ServerOptions, SecurityOptions, EvaluationOptions, end md\"\"\" Configuration options Pluto's settings are divided into length categories categories \"\"\" Docs.Binding Pluto.Configuration, categories 1 Docs.Binding Pluto.Configuration, categories 2 Docs.Binding Pluto.Configuration, categories 3 Docs.Binding Pluto.Configuration, categories 4 "},{"url":"en/docs/disable-cell/","title":"💡 Disabling cells","description":"How to disable a cell in Pluto, or disable a cell in the file.","tags":["docs","editor"],"text":"Disable a cellPluto allows you to disable a cell, which means that it will not get executed with reactivity. When one of the dependencies of a disabled cell changes, the disabled cell will not get executed as usual.Disable a cell by opening the Cell context menu menu in the top right of a cell input. Then click on Disable.Enable it again in the same menu, by clicking on Enable.Disabled cells are indicated by a ‘greyed-out’ appearance. Pressing the “Run” button (Shift-Enter) will not execute the cell, but it will save any changes to the cell code.In this video, the disabled cell no longer responds to changes in the count variable. (The same applies when count is defined in code, instead of with a slider.)ReactiveThe cell disabling feature is reactive – any cells that depend on a disabled cell will also be disabled. This ensures that the notebook remains consistent, and there is no code that executes with old values that no longer exist.This is also a really powerful feature, because you can easily disable a large number of cells at once, by disabling a core cell that is used in all of them.In this video, the last cell is disabled indirectly, because it depends on the disabled cell through the text variable.Other usesDisabling a cell can also be useful for other purposes, such as:Dramatic effect: You can use this when showing a piece of code, but you don’t want to show the result yet.Disable a cell in fileThere is also the option to disable a cell in the file. This makes no difference when running the notebook in Pluto, but the cell code will be stored as a Julia comment in the file.This is useful when you are writing a Pluto notebook file (.jl) that is also used as a Julia script. This lets you write code that is only executed when the notebook is used in Pluto, such as additional plots, testing, or more.Notice the gray markers to the right of the cells, marking a cell disabled in file (second cell) and a cell disabled indirectly in file (last cell).File formatBefore the cell is disabled in file, the .jl notebook file looks like:# ╔═╡ d5697b7b-a916-468c-9a2a-e84a87d7320f\n@bind count Slider(5:20)\n\n# ╔═╡ 6a653410-c595-45fb-8357-6ffe815e9d49\ntext = repeat(\"🎈\", count)\n\n# ╔═╡ 94216444-bcfb-4925-bc16-44b698181286\nsum(codeunits(text))\nAfter disabling the second cell in file, you get:# ╔═╡ d5697b7b-a916-468c-9a2a-e84a87d7320f\n@bind count Slider(5:20)\n\n# ╔═╡ 6a653410-c595-45fb-8357-6ffe815e9d49\n# ╠═╡ skip_as_script = true\n#=╠═╡\ntext = repeat(\"🎈\", count)\n  ╠═╡ =#\n\n# ╔═╡ 94216444-bcfb-4925-bc16-44b698181286\n#=╠═╡\nsum(codeunits(text))\n  ╠═╡ =#\nReactiveThe Disable in File feature is reactive, just like the “Disable” feature. This means that any cells that depend on a cell that is disabled in file will also be disabled in file. The reasons here are similar: it makes sense for consistency, and it makes it easy to disable a large number of cells at once."},{"url":"en/docs/education-showcase/","title":"🌟 Courses using Pluto","description":"Overview of courses taught using Pluto.jl","tags":["docs","education"],"text":"Courses taught with PlutoPluto.jl is a programming environment designed for education and is being used in several courses around the world. Pluto was developed alongside the free online course Introduction to Computational Thinking at MIT, with the goal of creating a programming environment that is powerful, helpful and interactive, without being too intimidating for students and teachers.List of coursesFeel free to add your course to this list by clicking “Edit this page” at the bottom of this page. Is your course not open source or not online? No problem, you can still add it without a URL.CourseTopicsYearNotes🇳🇱 Bayesian Machine Learning and Information Processing (5SSD0) (TU Eindhoven)Bayesian ML, signal processing, variational Bayes2026🎈 Co-developed with Pluto!🇺🇸 MIT 18.S191 — Introduction to Computational Thinking (MIT)scientific computing, epidemic modeling, climate modeling, raytracing, image processing2026🎈 Co-developed with Pluto!🇮🇹 Time-Domain Astrophysics (Università dell’Insubria, Como)Time-series analysis in astrophyisics2026🇩🇪 Research Software Engineering with Julia (University of Mainz)Julia programming, research software engineering, parallelism, type stability, multiple dispatch, accelerated computing2026Uses CT template🇩🇪 Höhere Mathematik I+II (University of Augsburg)fundamentals, calculus, linear algebra2025interactivity powered by PlutoSliderServer.jl🇬🇧 RCDS Introduction to Julia (Imperial College London)Julia programming2025🇬🇧 Introduction to Julia for Computational Science (Cambridge ICCS)Julia, computational science2025🌍 Julia Course (VEZY)Julia programming2025🌍 JuliaClimate Notebooks (JuliaClimate)climate science, global warming, CMIP6, sea surface temperature, marine ecosystems2025🇨🇭 Biological Data Science II: Machine Learning (BIO-322) (EPFL)cross-validation, gradient descent, neural networks, tree-based methods, unsupervised learning, reinforcement learning2025🇩🇪 Julia for Machine Learning (JuML) (TU Berlin)Julia, linear algebra, DataFrames, machine learning, automatic differentiation, deep learning2025Highly recommended!🇵🇹 Applied Computational Notebooks for Electric Machinery II (ISEL/IPL, in portuguese)DC Machines, 3-phase Synchronous Machines, Dynamics of Electrical Machines2025🌍 Statistical Rethinking in Julia (SR2TuringPluto)Bayesian statistics2024Based on McElreath’s Statistical Rethinking; uses Turing.jl🇩🇪 Mathematik für Informatiker 2b (Johannes Gutenberg-Universität Mainz)calculus, numerical methods, Fourier series, PDEs, image processing2024🇫🇷 Computational Economics for PhDs (SciencesPo Paris)optimization, parallel computing, dynamic programming, discrete/continuous choice2024🇬🇧 Macroeconomics (EC413) (London School of Economics)macroeconomics2023🇩🇪 Scientific Computing (TU Berlin)PDEs, finite volumes, finite elements, mesh generation, linear/nonlinear solvers, Julia, parallelization2022🇧🇷 Ciência de Dados e Computação Científica com Julia (UNINOVE, in portuguese)Julia, DataFrames, plots, JuMP optimization, Turing, ML, deep learning2022🌍 GeoStats.jl Tutorials (Online)Introduction to geostatistical modeling in Julia2020🇦🇷 Investigación Operativa (UTN-FRSN, in spanish)Introduction to Operations Reseach for Industrial Engineers2022-2026🇦🇷 Inteligencia Artificial aplicada a la ingeniería (UTN-FRSN, in spanish)Introduction to Machine Learning and Data Science for Industrial Engineers2022-2025\n    #courselist-wrapper {\n        overflow-x: auto;\n    }\n    table {\n        min-width: 600px;\n    }\n    :is(td,th):nth-child(3) {\n        /* white-space: nowrap; */\n        /* font-weight: bold; */\n        min-width: 4ch;\n        padding: 0;\n    }\nAre you using Pluto to teach a course? You can add your course to this list by clicking “Edit this page” at the bottom of this page. Is your course not open source or not online? No problem, you can still add it without a URL."},{"url":"en/docs/education/","title":"🎓 Pluto for your course","description":"How to use Pluto to teach Julia with interactive lectures and engaging assignments.","tags":["docs","education"],"text":"Pluto for educationPluto.jl is a programming environment designed specifically for education! If you are planning to teach a scientific course, Pluto might be a good fit for you and your students. Pluto only works with Julia, which is a great language for scientific education. Pluto is designed specifically for Julia, and addresses the needs that we had ourselves when teaching courses.Students and teachers are our primary target audience, and we are committed to We believe that there are enough ‘advanced’ tools for advanced users, but that a lot can be done to make programming more accessible to beginners.Learn more about why you should use Pluto for education, and how to use Pluto for lectures and homework assignments.Why is Pluto good for education?Here’s our evil plan to take over the world:We make programming and exploration easy – this makes it great for writing lectures notes. You can experiment with your idea, and when you’re done, you organize the code and add some text.Then we add interactivity in a very accessible way (easy, but not as flexible as some other tools) – and you can write awesome lectures with sliders, buttons and animation!When it’s the students’ turn to write code, we make Pluto as easy as possible to set up and use, with a coding experience that is designed specifically for users that are new to programming and Julia.Let’s look in more detail at writing lectures and assignments in Pluto.Why Julia for education?We believe that Julia is a great language for scientific education! Here are the main advantages from an educational perspective:Code as communication toolJulia has very expressive syntax, which can make your code look similar to the math or pseudocode that you use in your course. We think that (well-written) Julia code is relatively easy to understand by students and scientists, even if they don’t know Julia that well. Watch the TED talk by Alan Edelman about this topic.This is a core concept in Pluto – you can use code to tell your story, and not just outputs from code (like plots and numbers). That’s why Pluto lets you decide for each cell whether to show the code or not.Easy access to core CS and math conceptsUnlike Python, R and JavaScript, Julia gives you direct access to core CS concepts like memory, pointers, bytecode, baremetal performance and more, if you want! And unlike C++ and Rust, you also don’t have to worry about these things. This means that you can teach your course in a high-level way (to cover many topics), and also touch upon core CS concepts in a lecture, without having to switch to a different language.Good way to learn PythonLet’s be honest, many students will complain that your course is not using Python. Well, learning Julia is also an excellent way to learn Python! Julia teaches core programming skills that are very transferrable to Python – it’s not a waste of time. Even better, learning another language gives you a wider view of the programming landscape, which will help you be more creative.Connection to open source and the scientific communityThe Julia community is very open and welcoming, and Julia users are much more likely to contribute to open source projects than more established languages. This is a big advantage for students who are entering the scientific community, because Julia offers many opportunities to collaborate and get involved."},{"url":"en/docs/export-html/","title":"📗 Export to HTML","description":"How to export a Pluto.jl notebook to an HTML file.","tags":["docs","publishing","html","file","export","share","web"],"text":"Export to HTMLThis is a snapshot of your notebook with all outputs in a standalone HTML file. You can share this .html file via email, and other people can double-click the file to read your notebook.InfoImportant: you can open an HTML export file on any computer, you do not need to have Julia or Pluto installed!For some examples of HTML export files, check out our featured notebooks.Step 1Open your notebook in Pluto, and wait for all cells to finish running.Step 2Press the Share button in the top right.Step 3Choose “Static HTML”.Step 4Choose “Download HTML file”.You can learn more about pluto.land here.ReproducibilityWhat’s really cool about HTML export files is that they are reproducible: every HTML export file from Pluto includes the .jl source code! That means that someone who reads the notebook can also run the original code and make changes!Every HTML export contains an Edit or run button in the top right. When you press it, you see a screen where you can:Run the notebook with binder, a free service to run scientific notebooks in the cloud. This works on any browser (including mobile), without needing to install Julia or Pluto.Download the .jl notebook file that was used to generate the HTML export. You can open this file with Pluto.Offline supportHTML export files are all-inclusive, which means that you can open them without an internet connection. This is why the HTML files are quite large (around 8MB plus your content): it includes all the assets (JavaScript, CSS, fonts) that are needed to display the notebook.Some heavy assets like the JuliaMono font are not included in the file itself, and will load progressively if you have an internet connection.Using HTML filesThe HTML can be shared as a file (like PDF), and people can open it by double-clicking the file. But you can also host the HTML file online, and use it as a web page. Learn moreWhen sharing HTML files online, frontmatter can be used to set the title, description, and author of the page. This information is used in the HTML <meta> tags, which are important for search engines and social media sharing."},{"url":"en/docs/export-julia/","title":"📗 Export to Julia","description":"How to export a Pluto.jl notebook to a Julia file.","tags":["docs","publishing","file","export","share","web"],"text":"Notebook filePluto notebook files are stored as .jl Julia files. This file contains:Code for each cellSpecial comments (start with #) that Pluto uses to understand which code belongs to which cell.The exact version numbers of packages that were used. This is stored at the bottom of the .jl file, the Project.toml and Manifest.toml content.When you send your .jl notebook file to someone else, they can open the notebook in Pluto and see the same results. This concept is called reproducibility, and it is something we work very hard on at Pluto!Step 1Open your notebook in Pluto, and wait for all cells to finish running.Step 2Press the Share button in the top right.Step 3Choose “Notebook file”.InfoThe steps above are a quick way to get the .jl file. You can also Save your notebook on your computer by giving it a file name. In that case, the steps above just give a copy of your file.Notebooks as scripts.jl notebook files can also be run as a script. Since the .jl file just contains your cell code, you can also run it with Julia:> julia my_notebook.jl\nThe most useful application is to use include(\"my_notebook.jl\") in the REPL or a script to get variables from your notebook outside of Pluto."},{"url":"en/docs/export-pdf/","title":"📗 Export to PDF","description":"How to export a Pluto.jl notebook to a PDF file.","tags":["docs","publishing","pdf","file","export","share","web"],"text":"Export to PDFIf you want to print your notebook, or submit it as homework assignment, it might be useful to get a PDF file!When possible, we recommend sharing an HTML file instead of a PDF file. HTML files are great for reproducibility!Step 1Open your notebook in Pluto, and wait for all cells to finish running.Step 2Press the Share button in the top right.Step 3Choose “PDF”.Page layoutPluto tries to make your notebook look well on paper. One challenge is where to place “page breaks”. Our goal is:Don’t split cells between pages, unless necessary.Markdown headers should be at the top of a page.🌸 If your notebook does not look good on PDF, generate an HTML export and send it to the Pluto developers! 🌸"},{"url":"en/docs/export-plutoland/","title":"📗 Upload to pluto.land","description":"How to export a Pluto.jl notebook using pluto.land .","tags":["docs","publishing","html","export","share","web","pluto.land"],"text":"Upload to pluto.landpluto.land is a simple web service run by the Pluto.jl team that makes sharing your Pluto notebook exports super easy!You can upload a notebook to pluto.land to get a shareable public link, where people can read and download your notebook.There are two ways to upload a notebook to pluto.land:Option 1: Upload HTML fileThe first option is to go to pluto.land and upload a Pluto HTML export file that you have already downloaded. You will get a shareable link to your notebook on pluto.land.Option 2: Directly from PlutoThe second option is to upload your notebook directly from Pluto, without downloading the HTML file first.You follow the same steps as described in the HTML export guide, but instead of choosing “Download HTML file” in step 4, you choose “Upload to pluto.land”. When the upload is finished, you will get a shareable link to your notebook on pluto.land.Delete after uploadIf you uploaded a notebook by accident, you can delete it after uploading, by clicking the ‘trash’ icon next to the URL. This option is only available directly after uploading. Once you close the window, the notebook will be permanently available on pluto.land.More informationTo learn more about how pluto.land works, and how to use it, check out the pluto.land website. The website has an FAQ section with more details."},{"url":"en/docs/export-recording/","title":"🎥 Recording – experimental video mode","description":"How to use the recording feature of Pluto.jl to create a special HTML video file,","tags":["docs","publishing","recording","html","file","export","share","web"],"text":"Make a recording (preview)Pluto has one really cool experimental feature, and we’re curious what you think! You can make a Pluto recording, which is a bit like recording your screen to a video, but the result is an HTML web page!That means that while you watch the video, you can pause and scroll to a different section!Take a look at this example videoPlease try it out, and let us know what you think!Step 1Open your notebook in Pluto, and wait for all cells to finish running.Step 2Press the Share button in the top right.Step 3Choose “Record”.Step 4Click to start a recording. You can choose between recording with microphone audio or without audio (screen only).Step 5You are now recording! You can:Interact with @bind elements and see your notebook update.Scroll through the notebook.Speak! Audio can be recorded.Make code changes (currently, individual keystrokes cannot be recorded, you need to run the cell to make changes show in the recording).Step 6When you are done, press “Stop recording”. After a couple seconds, you can choose a location to store the .html file."},{"url":"en/docs/export/","title":"Export options – overview","description":"How to export a Pluto.jl notebook to HTML, PDF or a Julia file.","tags":["docs","publishing","pdf","html","file","export","share","web"],"text":"How to export a Pluto.jl notebookAfter writing your Pluto notebook, you have a couple options to export your notebook, to share with someone else. The following options are available directly from the Pluto editor:Notebook file (.jl) – This is how Pluto stores your notebook file, and you can share it directly with someone else so they can run your notebook.Static HTML – A snapshot of your notebook with outputs in a versatile format. You don’t need to have Julia or Pluto installed to view it.PDF – A traditional PDF document for printing or sharing online.Recording – A special type of video!To access these options, press the Share button in the top right.🌟 New: pluto.landCheck out the new pluto.land, a website to easily share your Pluto notebooks! A full tutorial can be found herePublishing on the webThe options above are useful if you want a file to share with someone else. If you want to publish your notebook on the web (with a URL), or if you want live interactivity (with @bind) on your website, you need one of the more advanced options below.Notebooks as websitesThere are various ways to publish your notebook as a website, which makes it ideal for sharing with others. Learn moreNotebooks as interactive websitesPluto notebooks can be interactive, using the @bind macro. But when you export your notebook to a file, the @bind interactions do not work. This is because @bind requires a running Julia process to work. Every time that you move a slider or click a button, a Julia process needs to calculate the new reactive values.So how do you get live interactivity on your website? With PlutoSliderServer.jl"},{"url":"en/docs/faq/","title":"💡 FAQ","description":"FAQ","tags":["docs","introduction"],"text":"How is Pluto.jl different from Jupyter?Pluto.jl was built from the ground up to be a fresh new notebook system, written in Julia. The main differences are that Pluto notebooks are reactive, and that your notebooks are stored as executable .jl files.What’s the deal with reactivity?You use cells to define variables and functions to be used later. In a reactive notebook, changing a variable or function will automagically re-evaluate all other cells that use it. Just like a speadsheet editor!Programming is hard sometimes. Even more so when you need to keep track not only of your code, but also of your session’s hidden state. Pluto gives you confidence that the code you see exactly matches the variables you’re working with, eliminating bugs before you even knew you had them.Will all cells be re-evaluated when I change something?No. Pluto.jl figures out the dependency graph between cells, and knows exactly which cells to re-evaluate, in which order. A cell never executes twice.Will my code be slower?Nope - Pluto.jl analyses your code, and then executes the code without modifications. Variables and functions are not wrapped in special objects. After analysis, your code will run on its own.Can I use Plots?Yes you can! All plotting back-ends should work right away.How to use multiple threads in Pluto.jl? nthreads() says 1 somehowYou can, but you need to set JULIA_NUM_THREADS environment variable as described in the documentation for the worker spawned by Pluto.jl to pick up.Can I use [my favourite package]?Yes you can! (Probably!) Your code is evaluated as-is, so if it works in the REPL or in Jupyter, it will work in Pluto.jl. There are some exceptions:packages that are made specifically for the REPL or JupyterDistributed, and packages that use it (#300)Can I open multiple notebooks at the same time?Yes! Click on the logo (  ) to go back to the welcome screen. You can use your browser tabs to see multiple notebooks simultaneously.Can I use Pluto remotely?If the server (where Pluto will run) and the client (the machine whose browser will use Pluto) are on the same network then set the host to 0.0.0.0 while launching Pluto (e.g Pluto.run(host=\"0.0.0.0\"). An example use case is if you have a headless raspberry pi and a laptop connected to the same wi-fi network in your home. You can run Pluto on the raspberry-pi and use your laptop’s browser for development.However if the server is remote and has a public ip you need to set up an SSH tunnel. First, log in to your server using SSH and start a Pluto server. Then open a local terminal on your own computer and type:ssh user@ipaddress -N -L 1234:localhost:1234\nwith user and ipaddress filled in accordingly. You can then go to http://localhost:1234/ on your own computer to get started! For more info and instructions for Windows, see this guide. This can come in handy if your server is on a cloud service such as AWS or Azure. The latter method can be used in the former case too provided an ssh client is available and enabled on both machines.Can I use @async to update values reactively on demand?Unfortunately not. Pluto.jl uses static code analysis to determine which cells to run next — it does not use wrappers or a polling mechanism to watch variables in real-time. However, the @bind macro might be able to do what you want! Have a look at the Interactivity sample inside Pluto. Feel free to open a GitHub issue if this doesn’t suit your needs.How can I load startup.jl?We want your notebooks to be reproducible, so our suggested method is that you copy and paste your personal setup script into a begin ... end block inside your notebook. This avoids implicit dependencies of your notebook. Alternatively, you could write include(\"path/to/startup.jl\"), but this will only work on your computer.How can I load a notebook upon launching Pluto?You can pass the notebook keyword argument to Pluto.run, e.g. Pluto.run(notebook=\"/path/to/notebook.jl\").How can I use a sysimage inside Pluto?Pluto.run() takes a keyword argument sysimage which can be used to add sysimage used by each notebook. To load the currently loaded sysimage, start pluto using:Pluto.run(sysimage=unsafe_string(Base.JLOptions().image_file))"},{"url":"en/docs/featured-notebooks/","title":"⭐️ Featured notebooks","description":"","tags":["docs","introduction"],"text":"⭐️ Featured notebooksCheck out some amazing Pluto notebooks created by the community! These notebooks are a good way to get started, and you can discover new things to do with Pluto.Browse featured notebooksSubmit your ownInterested in submitting one of your notebooks as a featured notebook?You don’t need to be an expert to write a featured notebook! The notebooks are designed to help beginning Pluto users get underway with their own ideas; as such, short tutorials on basic Julia concepts, or short examples of neat ideas, are very much welcome, and are a great way to contribute to the Julia community when you’re still learning yourself.That said, we also very much welcome experienced Julia programmers to share their work. Featured notebooks can highlight how you use Julia in your domain, bring attention to a neat package, or share exercises that you created for a course.Learn more"},{"url":"en/docs/files-open/","title":"📖 Open and move files","description":"How to open and move files from your computer or from the web","tags":["docs","file","navigation"],"text":"Pluto notebook filesPluto notebooks are stored as .jl files on your computer, and Pluto needs to know the exact location of each file to open, save, and manage it.When you create a new notebook, the notebook is stored temporarily in the ~/.julia/pluto_notebooks/ folder with a random name (something like Wild experiment 4.jl). This is a hidden folder, and we recommend saving your notebooks somewhere else (like your Documents folder) if you want to keep your work.The .jl extensionThe .jl extension is used because Pluto notebooks are valid Julia files – you can run them as Julia scripts, or use the include function in the REPL to start a REPL session with the notebook.You are free to use a different extension (like .plutojl), the extension is not required to open the file.How to open a notebook from your computerFirst, go to the Pluto main menu. Now you can type a notebook path in the textbox, and press Enter or click the “Open” button. You would need to enter the full path of the notebook into the blue bow. While you type, there will be autocompletion suggestions with folders and files.Finding file paths on your computerTo open a notebook, Pluto needs to know the full path of your .jl file — this is the complete address that tells your computer exactly where the file is located. The format of file paths differs depending on your operating system:On Windows:Paths start with a drive letter and use backslashes:An example is: C:\\Users\\fons\\Documents\\my_notebook.jlTo copy a file’s path: hold Shift, right-click the file in File Explorer, and select “Copy as path”For a detailed step-by-step guide, check out this Windows tutorialOn macOS:Paths start with a forward slash /A path may look like: /Users/fons/Documents/my_notebook.jlTo copy a file’s path: right-click the file in Finder, hold Option (⌥), and select “Copy … as Pathname”For a detailed step-by-step guide, check out this MacOS tutorialOn Ubuntu (and other Linux distributions):Paths start with a forward slash /They look like: /home/fons/Documents/my_notebook.jlTo copy a file’s path: right-click the file in your file manager (e.g., Nautilus), and select “Copy” or use the keyboard shortcut Ctrl+Shift+C in the file manager’s address barAlternatively, you can drag and drop the file into a terminal window to paste its full pathWhy so difficult?It would be really nice if you could just pick the notebook file from your file browser, instead of having to type the path. But this is not possible, because Pluto is a web application, which does not have access to your file system for security reasons. See this issue. BUT this feature is possible in the Pluto Desktop app (WIP)How to open an existing notebook fileWhen you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off.To open this temporary folderYou can quickly navigate to the temporary notebooks folder by running this command in Julia:run(`open ~/.julia/pluto_notebooks/`)  # macOS\nrun(`explorer ~/.julia/pluto_notebooks/`)  # Windows\nrun(`xdg-open ~/.julia/pluto_notebooks/`)  # Linux\nHow to open a notebook from the webYou can use Pluto to open a notebook from the web, using the URL of the notebook file. First, copy the URL of the notebook file. This URL probably ends with .jl. For example:https://github.com/JuliaPluto/featured/blob/main/src/basic/turtles.jlNext, go to the Pluto main menu. Now you can paste the URL in the textbox, and press Enter or click the “Open” button.The notebook will open in “Safe Preview” mode, which means that no code will be executed until you give permission.Open a notebook using the ClipboardYou can copy the complete contents of a .jl Pluto notebook file, and open it with Pluto. With the contents of a notebook file in your clipboard, go to the Pluto main menu. Now simply paste the contents anywhere on the page using Ctrl+V or Cmd+V, and it will be opened as a new notebook.The notebook will open in “Safe Preview” mode, which means that no code will be executed until you give permission.How to move filesThe path of your current notebook is displayed at the top of the Pluto interface. You can click on it to change the path — this allows you to:Move the notebook to a different folderRename the notebook fileSave a copy in a new locationAfter typing a new path, press Enter or click the save button to confirm the change. The notebook will be moved or renamed accordingly.Running featured notebooksOn the bottom of the Pluto main menu, you will find a large collection of featured notebooks – notebooks written by the Julia community, featured by the Pluto developers. These notebooks are a great resource to get inspired about new ways to use Julia and Pluto!Click on any featured notebook to read it. This will instantly load the notebook (prerendered on our servers), and interactive elements will work (this is done using PlutoSliderServer.jl). If you want to change code and run the notebook, simply click the “Edit or run” button in the top right of the screen. This will make a copy of the notebook on your computer that you can edit."},{"url":"en/docs/files/","title":"📄 Create, save and shutdown notebooks","description":"How to create, save and shutdown notebook files","tags":["docs","file","navigation"],"text":"How to create a new notebookFirst, go to the Pluto main menu. Then, click the “New” button. This will create a new empty notebook in the current Pluto session.TipYou can right click the “New” button, and select “Open in new tab”. This will open the new notebook in a new tab, and you can open more notebooks in parallel.How to save a notebookNotebooks are saved automatically when you run code. When you start typing new code in a cell, this code is not yet saved, but when you run the cell, the code is saved.When there are unsaved changes in a notebook, you will see a button in the top right corner of the notebook – the “Save” button. Clicking this button will run all unsaved cells in one batch, which will automatically save the notebook.How to preview and run a notebookWhen you first open a Pluto notebook, it opens in safe preview mode. This lets you explore the notebook without running any code yet. In this view, you can:Read through the code and verify you want to run itEdit code, move cells around, or hide cells, all without executing anything!View md\"\" and html\"\" blocks without interpolation (JS and CSS won’t run)When you’re ready to run the notebook:Click the “Run Notebook Code” button to startThe package environment will initializeAll cells will executeHow to shut down a notebook⚠️ Closing the browser tab doesn’t stop the notebook — it keeps running in the background. This means you can reopen the notebook anytime by navigating back to its URL in Pluto’s main menu, and it will appear exactly as you left it without needing to rerun all the cells.To actually shut down a notebook:Navigate to Pluto’s main menu (the home page with your list of notebooks)Find the notebook you want to shut down in the listClick the \nbutton on the left side of the notebook entryThis will completely shut down the notebook and stop its Julia process, freeing up system resources. The notebook will remain in your list so you can easily reopen it later (it will need to rerun from scratch when you open it again).To remove a notebook from the list: If you want to clear a notebook from your main menu entirely, click the “forget” button on the right side of the notebook entry. This only removes it from the list — the notebook file itself remains saved on your computer.Tip: To stop all running notebooks at once, you can close the Pluto server by pressing Ctrl+C in the terminal or command prompt where Pluto is running.To restart a notebook (restart kernel)If you want to restart a notebook that’s currently running — for example, to clear all variables and start fresh — simply shut it down using the  button and then reopen it by clicking on it in the list. This is equivalent to “restarting the kernel” in other notebook environments like Jupyter.If the notebook process crashes, for example due to an issue while precompiling or loading packages, Pluto automatically detects the interruption and offers to restart."},{"url":"en/docs/frontmatter/","title":"📰 Frontmatter","description":"How to use frontmatter in Pluto.jl notebooks.","tags":["docs","publishing","frontmatter","yaml","markdown","file","export","share","web"],"text":"FrontmatterFrontmatter is a way to add metadata to a Pluto.jl notebook, such as the title, description, authors, cover image, license, date and more. This data is used when sharing notebooks online, using Pluto HTML exports, PlutoUI.NotebookCard, PlutoSliderServer, PlutoPages or pluto.land.For example, the featured notebooks use frontmatter. When you see the list of all featured notebooks, notice how they all have a title, description, cover image and authors. This information is written is taken from the frontmatter of the notebook files.Frontmatter is stored in the .jl notebook file as a TOML block at the top of the file. You can use Pluto.frontmatter to read this data from Julia, and you can edit it using the frontmatter GUI in Pluto (or by editing the .jl file directly).The frontmatter GUIWhen editing a Pluto notebook, you can open the frontmatter editor by clicking the “Share button” in the top right.In the share menu, click the  icon to open the frontmatter editor.Here is a screenshot of the frontmatter editor. Scroll down to see more.In this editor, you can edit fields and add new fields. You are free to enter any data that you want (which you might want to use in your custom scripts), but some frontmatter entries have special meaning in the Pluto ecosystem.Special frontmatter entriesThe following keys have special meaning:title – the title of the document. When not used, the notebook filename is used as title. This is used in Pluto.jl HTML exports as the <title> tag.description – the description of the document. This is used in Pluto.jl HTML exports as the <meta name=\"description\" content=\"...\"> tag.image – the URL of the cover image of the document.date – the date of the document.license – the license of the document.tags – a vector of tags for the document, used by the PlutoPages.jl sidebar and search, and PlutoSliderServer.jl.layout – the PlutoPages.jl layout file of the document.order – the order of the document within its category.Open Graph (OG) tagsThe following keys are used as Open Graph (OG) tags in Pluto.jl HTML exports (using <meta property=\"og:...\">):title, type, description, image, article:tag, url, audio, video, site_name, locale, locale:alternate, determiner.Setting these values helps with sharing notebooks on social media and search engine optimization.The author fieldThere is also a vector author that is used to provide the authors of the notebook. The following fields have special meaning in the Pluto ecosystem:name – the name of the author.url – the URL of the author’s website. If this is a github user/organization URL, the author’s avatar will be shown in the notebook.image - the URL of the author’s avatar. This is not needed if the url is a github URL.PlutoPages.jlIf you are using PlutoPages.jl to write your website, you should at least set the following frontmatter entries for every page: layout and tags. (layout is the name of the layout file in the src/_includes/ directory.)Featured notebooksIf you are writing a featured notebook, check out other featured notebook files to see which frontmatter entries are required.Accessing frontmatter from JuliaIf you are writing a script to process Pluto notebooks, you can access the frontmatter data using the Pluto.frontmatter function. This function takes a notebook path as an argument, and returns a Dict with the frontmatter data.path = \"/path/to/notebook.jl\"\nfrontmatter = Pluto.frontmatter(path)\n@info \"Written by\" frontmatter[\"author\"]"},{"url":"en/docs/get-involved/","title":"🤝 Get involved","description":"How to contribute or give feedback to Pluto","tags":["docs","collaborate","feedback","localization","navigation"],"text":"How to contributeTake a look at our localization documentation to get started! Or at our developer instructions\nWe look forward to your contributions! 💛We’re also happy to hear about any issues we may have missed. Before opening a new one, please take a moment to check this guide.Ask questions and discussIf you have questions about using Pluto or want to discuss ideas, there are several places where you can meet fellow Pluto users.NoteGet involved! If you are shy to ask a question or post your work, that’s probably a good sign that you should do it! The Julia community is very welcoming and helpful, and people will be happy to hear from you!DiscourseThe JuliaLang Discourse is a very nice platform for the wider Julia community. There is a Pluto category where you can ask questions and share your work.ZulipThe JuliaLang Zulip is an open source chat platform in your browser. The Julia community has a very active Zulip, and there is a Pluto channel. To join:Click here to join the Julia zulip: https://julialang.zulipchat.com/Create an account, or log in with github/google.After logging in, you need to Add the Pluto stream using this button:That’s it, see you there!InfoThere is also a stream called Pluto.jl developers, if you are interested in contributing to Pluto.SlackThere is also the JuliaLang Slack, which is a commercial chat platform (not open source). You can ask questions in the #pluto channel. The Pluto developers don’t regularly check this channel.How to give feedback to developersHow is your experience with Pluto? Pluto has a built-in feedback form for complaints, praises, nice-to-haves, or any suggestions you might have, we’re always glad to hear from you!The easiest way to reach us: Use the built-in feedback tool at the bottom right of each notebook. 👨‍🏫Your feedback goes directly to the Pluto developers in a private databaseFeedback is anonymous by default, but you can optionally leave your email addressWe might contact you for more details or to share a solution 😉You can also reach us through Julia community channels:DiscourseJuliaLang zulip - we have a Pluto channel, just pop by!JuliaLang slackOr email us directly :) you can find Pluto developers’ email addresses on their GitHub profiles.EducationWe are specially interested in feedback from students and teachers:Using Pluto to teach? We’d love to think together about your courseLearning Julia with Pluto? Let us know how it’s going and what could be betterWe’re working to make Pluto helpful for new Julia users, so your feedback is invaluable! 🎉"},{"url":"en/docs/governance/","title":"Governance","description":"The governance model for the Pluto.jl project.","tags":["docs","internals","advanced","governance","open source"],"text":"GovernancePluto is a Free Open Source Software project. The Pluto project includes Pluto.jl, and all other projects in the JuliaPluto GitHub organisation. The project is developed by volunteers, employees of organizations that support Pluto, and by contributors with funding from Open Source grants. This document outlines the decision-making process behind Pluto’s development, and how other people can get involved.We welcome new contributors! If you want to contribute, please check out our contributing guidelines, and get in touch with the Pluto developers.Decision makingDecisions about the project are made by the core developers, or by other (new) contributors in collaboration with core developers. Decisions that should be made by (or approved by) core developers include:New featuresRefactoringPackage interoperabilityUI/UX design changesPublic APIReleasesAlways welcomeSome contributions are less contested, and you can assume that this work will be appreciated. This includes:Bug fixes (especially GitHub Issues labeled Bug)Localization (info)Compatibility workOptimization (if it includes an improved benchmark)Fixing spelling errorsAccessiblity improvementsThis means that (new) contributors can always work on these areas independently, and open a PR without discussing it first.Core developersThe core developers of the Pluto ecosystem include (in alphabetical order):Fons van der PlasMikołaj BocheńskiMichiel DralΠαναγιώτης (Panagiotis) ΓεωργακόπουλοςPaul BergYou can find their contact information on their GitHub profiles. Feel free to reach out!Subprojects – additional core developersSome subprojects of the Pluto ecosystem (like some packages) have additional core developers. Anyone with “Maintain” or “Admin” rights to a repository is considered core developer of that project or package. This includes (but not limited to):pluto.jl website (link): Boshra Ariguibfeatured (link): Boshra Ariguib, Benedikt Ehinger, Luka van der PlasPlutoDesktop (link): Boshra Ariguiblezer-julia (link): Sergio Vargas, Andrey PoppMalt.jl (link): Sergio Vargas, Michael HatherlyPlutoTeachingTools.jl (link): Adrian Hill, Eric Ford, Fabian GreimelHypertextLiteral.jl (link): Clark EvansBecoming a core developerAny core developer can add additional core developers. Subproject core developers can add additional core developers to their subprojects. If you are interested in becoming a core developer, get in touch! You are expected to have familiarity with the project, an interest in maintaining it, and you should get to know the other contributors.Any (subproject) core developer can step down (temporarily or permanently) from their role at their own choice.Community workPluto is not just a codebase, but also a community project. Our community work inlcudes:Issue tracking, triage, review\nOur GitHub Issues, Discussions and PRs.Online discussions (Discourse, Zulip, Slack, etc)Documentation (this website)Featured notebooks (info)Conference talks, workshops, meetups, etcDeveloper meetups, onboarding, mentoring, etcNote that our code of conduct applies to these spaces.Community leadersAll core developers are also community leaders, but we also have some additional community leaders who focus on the non-code aspects of the project. These include (in alphabetical order):Gerhard Dorn"},{"url":"en/docs/homework/","title":"📄 Homework","description":"How to use Pluto to teach Julia with interactive homework assignments.","tags":["docs","education"],"text":"Pluto for homework assignmentsWe want people to learn by doing. There are several ways for students to get involved in the course by programming themselves using Pluto. For example:Open assignments – students can create a new notebook from scratch to solve a problem.Guided assignments – you can write a notebook with assignments, and let students fill in the gaps. Pluto is great for this! For some examples, take a look at the homeworks from Computational Thinking at MIT.Remixing lecture notes – since Pluto notebooks are reproducible, students can easily run the lecture notes (on binder, or locally) and play around with the code.Guided assignmentsPluto is great for a style of assignment, which we will call “guided assignments”.The idea is a notebook that contains:Text to explain the assignment.Cells with missing content, where students fill in their code.(optional) Cells that check the student’s answer, and give feedback. Because of reactivity, these cells will re-run automatically when students change their answer. This gives an interactive experience for students with instant feedback! You can use PlutoTeachingTools.jl for this.Bonus text and resources to explain more concepts. For example, you can add a foldable section that explains how parametric types work in Julia, for students who want to dive deeper.ExamplesFor some examples, take a look at the homeworks from Computational Thinking at MIT, in particular Homework 1 and Homework 3, which are also featured Pluto notebooks.JuliaCon talkJuliaCon 2021 presentation on using Pluto at MIT, with interactive lectures and guided assignments.PlutoSplitter.jlOne tool that may help you with guided assignments is PlutoSplitter.jl. This package lets you write a homework notebook with all the solutions already filled in, and then split it into two files: one with the solutions, and one with all answers removed. This lets you work on your answer-checking code easily, and then generate an assignment file for students.Open assignmentsPluto is also a good tool for open-ended assignments, where students write the complete notebook themselves. For example, you could ask students to “Write a notebook that explores the Collatz conjecture, and explain it in an interactive way”. The end result could be an interactive article, or a presentation. Pluto is an easy environment for Julia newcomers to work in, which makes it easy for students to write a complete interactive article on their own.Didactically, open-ended assignments in Pluto are really great! Pluto is designed to be a good playground to explore a computational topic. It’s safe to try things, and easy to use. By asking students to write an interactive article, you force them to dive into a topic and understand how it works.From a technical perspective, Pluto’s reproducibility is really useful. It means that students can write a notebook with packages, interactivity, plots, etc., and you will know that you can open the notebook on your computer for review.Manual GradingPluto notebooks are quite easy to review because of the different export formats and Pluto’s reproducibility. From Fons’s experience, grading is the easiest if you ask students to hand in the assignment in HTML Export format (you can link students to the documentation for instructions). HTML files are fast to open and review (you don’t need to run student code). HTML files also contain the .jl notebook file if needed. I would recommend this over collecting Julia or PDF files.Canvas SpeedGraderIf you are using Canvas for your course, you can use the SpeedGrader to review HTML files. This works very well in my experience! You can require submissions to be in HTML format, and speedgrader will let you cycle between student notebooks for grading.You can combine this with a “Grading Rubric”. Then you will see the rubric next to the student’s notebook.Automatic GradingThere are several small projects to do autograding of Pluto notebooks. TODO (feel free to contribute)"},{"url":"en/docs/images/","title":"🖼️ Images","description":"How to add images to your Pluto notebook.","tags":["docs","writing","images","image","picture","photo","picture","photo","image","picture","photo"],"text":"Adding images to your notebookYou can add images to your Pluto notebook quite easily! But it is different from what you might be used to in Jupyter, Word, or Google Docs.Method 1: Using imgur and MarkdownThe easiest way to add images to your notebook is to upload the image to imgur.com (or a similar service), and then use the Markdown syntax to embed the image URL.First, go to imgur.com and upload your image. (You don’t need to create an account.) Now, click on the ..., and then “Get Share Links”.We want the URL that points directly to the image. It should end with .png, .jpg, or something similar. You can get it from the “BBCode” option.This should give you a URL like this:https://i.imgur.com/qHCI8RS.png\nUsing the image URL in MarkdownIn Pluto, create a new cell. We will use the Markdown image syntax to embed the image.md\"\"\"\n\n![Description of the image](https://i.imgur.com/qHCI8RS.png)\n\n\"\"\"\nYou can also use PlutoUI.Resource or HypertextLiteral.jl to have more control over how the image is displayed.Method 2: Using an image from GitHubIf your image is stored in a repository on GitHub, you can use the Markdown syntax to embed the image URL.First, go to the image on GitHub. Click on the ..., and then “Copy permalink”. Now you have a permalink, which means that the URL will keep working, even if the repository changes.This permalink looks like:https://github.com/fonsp/fonsp.github.io/blob/b74c865b0292006af89496418c2c19f48517ca2e/img/doggoSmall.jpg\nNow, you need to add ?raw=true to the end of the URL, to get a URL that points directly to the image. This looks like:https://github.com/fonsp/fonsp.github.io/blob/b74c865b0292006af89496418c2c19f48517ca2e/img/doggoSmall.jpg?raw=trueUsing the image URL in MarkdownIn Pluto, create a new cell. We will use the Markdown image syntax to embed the image.md\"\"\"\n\n![Description of the image](https://github.com/fonsp/fonsp.github.io/blob/b74c865b0292006af89496418c2c19f48517ca2e/img/doggoSmall.jpg?raw=true)\n\n\"\"\"\nYou can also use PlutoUI.Resource or HypertextLiteral.jl to have more control over how the image is displayed.Method 3: Using a local imageYou can also embed images from your computer in Pluto notebooks, but we want to issue a warning here. It is often a better idea to use images hosted online (like imgur or GitHub).WarningEmbedding images from your computer means that the notebook will not work if you open it on a different computer.Images in the same repositoryA special case is when the image is in the same repository as the notebook. In this case, other people can also see the image, if they clone the repository and run the notebook that way.But if people run the notebook directly (with Binder, or by running the file without downloading the full repository), the image will not work.To embed an image from your computer, you can use the PlutoUI.LocalResource:using PlutoUI\nPlutoUI.LocalResource(\"../images/dogs.png\")"},{"url":"en/docs/","title":"🙋 Introduction","description":"","tags":["docs","introduction"],"text":"Welcome to Pluto.jl!This is the documentation website Pluto.jl, a reactive, educational notebook for Julia. Pluto is Free Open Source Software (MIT License). You can install Pluto for free and try it today!Discovering Pluto?To get a quick overview of Pluto, check out our homepage.If you want to dive deeper, take a look at the sidebar on the left. The sidebar is divided into sections, which are useful for different types of users. If you are new to Pluto, I recommend skipping the sections labeled “Advanced”.Looking for something specific?If you are looking for something specific, you can use the search bar in the top left, or below. It’s not powered by AI (hihi) and it works pretty well!Search documentation"},{"url":"en/docs/install/","title":"🌼 How to install","description":"","tags":["docs","introduction"],"text":"Install Pluto on your own computer👉 Go to plutojl.org/#install for instructions!System requirementsPluto works on Windows, Linux, MacOS, ChromeOS and Android. You need a computer with at least 4GB RAM, but 8GB is recommended for running multiple notebooks in parallel, or for using large packages.Pluto needs Julia to be installed, we recommend the latest version. Unreleased (alpha/beta preview) versions of Julia do not work well with Pluto.Pluto also needs a web browser to work. Make sure that your web browser is up-to-date, as Pluto uses many modern web technologies to work. Some browser extensions can break Pluto, such as Privacy Badger. You can disable these extensions for the Pluto domain (usually http://localhost:1234/).You do not need to be a system administrator to install Julia and Pluto.ChromeOSPluto works on a chromebook! You need to set up the Linux development environment, and then follow the Linux installation instructions as usual!iPad and iOSIt is not possible to run Julia on iPad or iOS (we think)… But you could run Pluto on another computer or a web server, and access Pluto remotely on your iPad or iOS phone.Pluto without installationYou can try Pluto in your browser without installation before installing! Go to plutojl.org/#try to learn more. Note that your files will not be stored in the cloud!Use Pluto in the cloudIf you want to use Pluto without installation for more serious projects, there are a couple of options:Jolin Cloud – jolin.io offers a cloud service for Pluto notebooks, with additional real-time data featuresJuliaHub – see the documentationCoCalc – see the documentation(EU research staff only) European Open Science Cloud – You get 10 Medium (4 vCPU, 8GB RAM) notebook compute hours per day if you are staff/faculty/employee of an EU research institute (like a university).With these three options you can store notebooks in the cloud, and you can also try bigger computers and GPUs. Jolin and JuliaHub also let you publish notebooks as public/private websites."},{"url":"en/docs/isolated-cell/","title":"Isolated Cells – notebooks as web apps","description":"Use isolated cells to embed one or more Pluto cells in a minimalistic way, to make a web app.","tags":["docs","widgets","isolated-cell","advanced"],"text":"Isolated Cells – notebooks as web appsPluto has a featured called “isolated cells”, which lets you embed one or more cells in a very minimalistic way. This is really useful if you want to use Pluto to develop a web app.With isolated cells:No Pluto UI is shown (like “Edit or Run”, binder, cell markers, etc.)All cell inputs (code) is hiddenAll cells display in full width and there are no marginsCells can be reorderedHow to use isolated cellsTo use isolated cells, you first need to write a notebook that is hosted somewhere as HTML. This is most useful for notebooks that are hosted using PlutoSliderServer.jl, so that you can use @bind to make your web app interactive.As an example, let’s work with the following notebook:https://featured.plutojl.org/basic/turtles-art.htmlWe will use “isolated cells” to make the final artwork in the notebook into its own web app. Currently, the notebook looks like this:Find the Cell IDsNext, you need to find the cell IDs of the cells that you want to isolate. You can find this in the .jl notebook file, as comment before each cell.You can also right-click on the cell in the browser, click “Inspect Element”, and then find the wrapping pluto-cell element. The id attribute of this element is the cell ID.In this example, the cell IDs are:e51d4b19-fa30-4643-8d12-407941a4757d\n6deab6a2-f298-42a8-9c86-db8a2a26ac17\nc668c791-9c3b-4eed-babe-9a484a88b68e\nCreate the URLNow, we use a URL query parameter to tell Pluto to isolate these cells. Add ? to the URL, and then add isolated_cell_id=... for each cell ID, separated by &.This gives:https://featured.plutojl.org/basic/turtles-art.html?isolated_cell_id=e51d4b19-fa30-4643-8d12-407941a4757d&isolated_cell_id=6deab6a2-f298-42a8-9c86-db8a2a26ac17&isolated_cell_id=c668c791-9c3b-4eed-babe-9a484a88b68eTry it out! It should look like this:"},{"url":"en/docs/javascript-api/","title":"JavaScript API","description":"Use JavaScript to make your own interactive visualizations!","tags":["javascript","web","widgets","advanced","docs"],"text":" A Pluto.jl notebook v0.20.14 frontmatter license url \"https github.com JuliaPluto featured blob 2a6a9664e5428b37abe4957c1dca0994f4a8b7fd LICENSES Unlicense\" image \"https upload.wikimedia.org wikipedia commons 9 99 Unofficial JavaScript logo 2.svg\" order \"3\" title \"JavaScript API\" tags \"javascript\", \"web\", \"widgets\", \"advanced\", \"docs\" license \"Unlicense\" description \"Use JavaScript to make your own interactive visualizations \" date \"2024 04 24\" layout \"layout.jlhtml\" frontmatter.author name \"Pluto.jl\" url \"https github.com JuliaPluto\" using Markdown using InteractiveUtils This Pluto notebook uses bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of bind gives bound variables a default value instead of an error . macro bind def, element format off return quote local iv try Base.loaded modules Base.PkgId Base.UUID \"6e696c72 6542 2067 7265 42206c756150\" , \"AbstractPlutoDingetjes\" .Bonds.initial value catch b missing end local el esc element global esc def Core.applicable Base.get, el ? Base.get el iv el el end format on end using HypertextLiteral using PlutoUI md\"\"\" JavaScript API ` script ` tags included in HTML output will be executed by Pluto, and you can use this to make interactive and dynamic widgets In your code, you will mostly be using Web APIs your code runs directly in the browser , like DOM manipulation. Use javascript.info https javascript.info or MDN https developer.mozilla.org to learn more about Web APIs. You can also import JavaScript libraries and frameworks and use them in your widget. We think the Web APIs and modern JavaScript are very powerful, and you should be able to do anything you want However, we decided to add a small amount of extra functionality to make it easier to write code specifically for Pluto outputs. \"\"\" md\"\"\" Debugging The HTML, CSS and JavaScript that you write run in the browser, so you should use the browser's built in developer tools https developer.mozilla.org en US docs Learn Common questions What are browser developer tools to debug your code. Check to make sure that you are able to debug JavaScript code \"\"\" htl \"\"\" script console.info \"Can you find this message in the console?\" script \"\"\" md\"\"\" And HTML and CSS \"\"\" htl \"\"\" style .cool class font size 1.3rem color purple background lightBlue padding 1rem border radius 1rem style div class \"cool class\" Can you find out which CSS class this is? div \"\"\" html\" span id currentScript \" md\"\"\" `currentScript` – Selecting elements When writing the javascript code for a widget, it is common to select elements inside the widgets to manipulate them. In the number of clicks example above, we selected the ` span ` and ` button ` elements in our code, to trigger the input event, and attach event listeners, respectively. There are a numbers of ways to do this, and the recommended strategy is to create a wrapper ` span `, and use `currentScript.parentElement` to select it . `currentScript` When Pluto runs the code inside ` script ` tags, it assigns a reference to that script element to a variable called `currentScript`. You can then use properties like `previousElementSibling` or `parentElement` to \"navigate to other elements\". Let's look at the \"wrapper span strategy\" again. ```htmlmixed htl \"\\\"\" the wrapper span span button id \"first\" Hello button button id \"second\" Julians button script const wrapper span currentScript.parentElement we can now use querySelector to select anything we want const first button wrapper span.querySelector \"button first\" console.log first button script span \"\\\"\" ``` \"\"\" md\"\"\" Why not just select on `document.body`? In the example above, it would have been easier to just select the button directly, using ```javascript ⛔ do no use const first button document.body.querySelector \"button first\" ``` However, this becomes a problem when combining using the widget multiple times in the same notebook , since all selectors will point to the first instance. Similarly, try not to search relative to the ` pluto cell ` or ` pluto output ` element, because users might want to combine multiple instances of the widget in a single cell. \"\"\" html\"\"\" span id value span span id input span span id bond span \"\"\" md\"\"\" `value` – Custom ` bind` value You can use JavaScript to write input widgets to be used with Pluto's ` bind`. The `input` event can be triggered on any object using ```javascript obj.value ... obj.dispatchEvent new CustomEvent \"input\" ``` For example, here is a button widget that will send the number of times it has been clicked as the bound value \"\"\" bind hello htl \"\"\" div button Click me button script let val 0 const div currentScript.parentElement const button div.querySelector \"button\" button.addEventListener \"click\", 🐸 Set the value of the div element and trigger an event 🐸 div.value val div.dispatchEvent new CustomEvent \"input\" script div \"\"\" hello md\"\"\" Default value `missing` When you write ` bind x Widget ` in your notebook, what is the initial value of `x`? By default, the macro ` bind` will set `x` to `missing` https docs.julialang.org en v1 manual missing , which will be the value of `x` while other cells are also running. Once all cells completed running, your browser can send the `.value` that it got from JavaScript, and cells that depend on `x` will run again with the value. These messages were debounced while cells were running, see section below. This means that simple JavaScript powered custom ` bind` widgets will trigger two runs when used in a notebook a first run with value `missing`, and a second run with the first value from JavaScript. `AbstractPlutoDingetjes.Bonds.initial value` To solve this, you can use `AbstractPlutoDingetjes.Bonds.initial value` https plutojl.org en docs abstractplutodingetjes initial value to tell Julia what the first value will be. This will then be used as the first value instead of `missing`. And if the first bond update from JavaScript is exactly the same, then this first bond update will not trigger a reactive run. \"\"\" md\"\"\" Debouncing Pluto automatically debounces all bonds while cells are running, no intermediate values are sent. Once all cells completed running, any queued bond updates are sent in one batch, but if the value of the same bond changed multiple times, only the last value is set, and intermediate values are discarded. This prevents a \"queue of updates\" that you could get when a bond controls a visualisation that takes a while to run. You could try it below \"\"\" bind fun fast Slider 1 100 fun fast bind fun slow Slider 1 100 let sleep 1 fun slow end html\" span id import \" md\"\"\" `import` – script loading To use external javascript dependencies, you can load them from a CDN, such as jsdelivr.com https www.jsdelivr.com esm.sh https esm.sh Just like when writing a browser app, there are two ways to import JS dependencies a ` script ` tag, and the more modern ES6 import. Technically, this is not API added by Pluto, this will work in any browser context. But we thought it's good to mention here. Loading method 1 ES6 imports We recommend that you use an ES6 import https developer.mozilla.org en US docs Web JavaScript Guide Modules if the library supports it. If it does not, you might be able to still get it using esm.sh https esm.sh Awkward note about syntax Normally, you can import libraries inside JS using the import syntax ```javascript ⛔ do no use import confetti from \"https esm.sh canvas confetti 1.4.0\" import html, render, useEffect from \"https cdn.jsdelivr.net npm htm 3.0.4 preact standalone.mjs\" ``` In Pluto, this is currently not yet supported https github.com JuliaPluto Pluto.jl issues 992 , and you need to use a different syntax as workaround ```javascript ✔ use const default confetti await import \"https esm.sh canvas confetti 1.4.0\" const html, render, useEffect await import \"https cdn.jsdelivr.net npm htm 3.0.4 preact standalone.mjs\" ``` \"\"\" md\"\"\" Loading method 2 script tag ` script src \"...\" ` tags with a `src` attribute set, like this tag to import the d3.js library ```html script src \"https cdn.jsdelivr.net npm d3 6.2.0 dist d3.min.js\" script ``` will work as expected. The execution of other script tags within the same cell is delayed until a `src` script finished loading, and Pluto will make sure that every source file is only loaded once, even if the same ` script ` is included multiple times in multiple cells. \"\"\" md\"\"\" Pinning versions When using a CDN almost never want to use an unpinned import. Always version your CDN imports ```js ⛔ do no use \"https esm.sh canvas confetti\" \"https cdn.jsdelivr.net npm htm preact standalone.mjs\" ✔ use \"https esm.sh canvas confetti 1.4.0\" \"https cdn.jsdelivr.net npm htm 3.0.4 preact standalone.mjs\" ``` \"\"\" html\" span id invalidation \" md\"\"\" `invalidation` – cleanup In a ` script ` you can use the variable `invalidation` , which is a `Promise` https javascript.info promise basics that resolves when the display is about to disappear. You can use this to clean up resources. ```html htl \"\"\\\" script invalidation.then cleanup here script \"\"\\\" ``` 😉 To ObservableHQ users this is the same API as Observable \"\"\" md\"\"\" As a silly example, here is a widget that displays a `String`, and it loops through each of the letters, showing the UTF 16 character codes. The looping animation is created with `setInterval`, and when the display disappears, we use `invalidation` to call `clearInterval` and stop the loop. Why do we need this? Every time you change the text in the `TextField`, this triggers a re render of the cell. If we would not call `clearInterval`, then each text would create a new interval, slowly taking up more resources and slowing down the browser. \"\"\" bind some text TextField default \"Gecko\" htl \"\"\" div h6 some text h6 p 🔡 Letters span style \"font family monospace font weight 900 \" span p script const span currentScript.parentElement.querySelector \"span\" const original text some text let i 0 const interval handler setInterval const index i % original text.length const char original text index span.innerText ` \\ index \\ char code \\ char.codePointAt 0 ` i , 500 invalidation.then clearTimeout interval handler script div \"\"\" html\" span id return \" md\"\"\" `return` – generate DOM from JavaScript If you ` script ` tag returns a `HTMLElement` like a ` div ` or ` input ` , Pluto will prepend that element before the ` script ` element that generated it. This makes it easier to use JavaScript code to create a DOM element. The element is added before , not after the script, so that it's a bit easier to use with ` bind`. \"\"\" htl \"\"\" script const element document.createElement \"h5\" element.innerText \"Whoopsiedoo \" element.style.color \"orange\" return element script \"\"\" details \"Show with syntax highlighting\", md\"\"\" ```htmlmixed script const element document.createElement \"h5\" element.innerText \"Whoopsiedoo \" element.style.color \"orange\" return element script ``` \"\"\" md\"\"\" info \"Persistant display\" Little technical note that you could ignore if the following conditions are met The cell re runs reactively , i.e. because one of the referenced variables re runs, not because you run the cell itself The old display and the new display have an `id` attribute set to the same value. Then the DOM element returned by the old script is shown as placeholder while the new script is running JS runs synchronously, but using top level `await` can cause a delay . This prevents a flash of empty content in between cell renders. In particular, if the new script happens to `return` the exact same element using `this` persistence , then that means the DOM element will always be displayed. \"\"\" html\" span id await \" md\"\"\" `await` – top level support You can use `await` in the top level code of your script. And when your script uses `await`, Pluto will wait for the script to complete before executing the next script. You can use top level `await` to `import` libraries and more. `await` is also used internally by `AbstractPlutoDingetjes.Display.published to js`. Here is a silly example, showing that use can use `await` and that scripts execute sequentially \"\"\" bind await example val TextField default \"coolbeans\" widget htl \"\"\" div p Loading... p script const p currentScript.previousElementSibling const val await example val await new Promise resolve setTimeout p.innerText val resolve , 1000 script div \"\"\" htl \"\"\" widget widget widget \"\"\" html\" span id observablehq \" md\"\"\" ObservableHQ stdlib Pluto is inspired by observablehq.com https observablehq.com , an online reactive notebook for JavaScript. It's REALLY good, try it out We design Pluto's JavaScript runtime to be close to the way you write code in observable. Read more about the observable runtime in their interactive documentation https observablehq.com observablehq observables not javascript . You will find that many features `this`, `return`, `invalidation`, `await` are similar in Pluto and Observable. The following is different in Pluto JavaScript code is not reactive, there are no global variables. Cells can contain multiple script tags, and they will run consecutively also when using `await` We do not yet support async generators, i.e. `yield`. We do not support the observable keywords `viewof` and `mutable`. In Pluto, the `observablehq stdlib` https github.com observablehq stdlib library is pre imported, and you can use `DOM` `Files` `Generators` `Promises` `now` `svg` `html` `require` Currently not supported are `FileAttachment` `md` `Mutable` `resolve` `tex` `width` If you need these libraries, just get in touch. We are also using an outdated version of the stdlib. If you want the latest version, get in touch You can use these libraries in top level scripts, like `html` in this example \"\"\" htl \"\"\" script return html` h5 Hello world h5 ` script \"\"\" html\" span id lodash \" md\"\"\" Lodash The Lodash https lodash.com library is pre imported, and is available with ` ` inside your code. \"\"\" htl \"\"\" script const data rand 1 10, 15 const parted .partition data, n n % 2 return html` ul \\ .map parted, ns return html` li \\ ns.join \", \" li ` ul ` script \"\"\" html\" span id this \" md\"\"\" `this` – stateful output In Pluto's runtime, there is a distinction between two types of ways that a cell can run 1. An explicit run a run triggered by user input Ctrl S, Shift Enter or clicking the play button or a cell deletion. 2. A reactive re run the cell runs because one of the variables referenced in the cell was redefined by another cell run. One difference is the JavaScript API `this` for an explicit run , the variable `this` is set to `undefined`. But with a reactive run , `this` will take the value of the last thing that was returned by the script. In particular, if you return an HTML node, and the cell runs a second time, then you can access the HTML node using `this`. Two reasons for using this feature are Stateful output you can persist some state in between re renders. Performance you can 'recycle' the previous DOM and update it partially using d3, for example . When doing so, Pluto guarantees that the DOM node will always be visible, without flicker. ☝️ Caveat ` script id ... ` This feature is only enabled for ` script ` tags with the `id` attribute set, e.g. ` script id \"first\" `. Without an `id`, `this` will always be set to `window`. Think of setting the `id` attribute as saying \"I am a Pluto script\". There are two reasons for this One Pluto cell can output multiple scripts, Pluto needs to know which output to assign to which script. Some existing scripts assume that `this` is set to `window` in toplevel code like in the browser . By hiding the `this` feature behind this caveat, we still support libraries that output such scripts. What should the `id` attribute be? This is a bit awkward we don't know yet. For now, just use the name of your favourite ice cream, but we are working on something better https github.com JuliaPluto AbstractPlutoDingetjes.jl pull 7 . Please comment on that PR if you want it \"\"\" trigger \"edit me \" let trigger html\"\"\" script id \"something\" console.log \"'this' is currently \", this if this null return html` blockquote I am running for the first time blockqoute ` else return html` blockquote b I was triggered by reactivity b blockqoute ` script \"\"\" end details \"Show with syntax highlighting\", md\"\"\" ```htmlmixed script id \"something\" console.log \"'this' is currently \", this if this null return html` blockquote I am running for the first time blockqoute ` else return html` blockquote b I was triggered by reactivity b blockqoute ` script ``` \"\"\" md\"\"\" Example d3.js transitions Type the coordinates of the circles here \"\"\" bind positions TextField default \"100, 300\" dot positions try parse. Int , split replace positions, ',' ' ' catch e 100, 300 end dot positions 100, 300 edit me md\"\"\" Notice that, even though the cell below re runs, we smoothly transition between states. We use `this` to maintain the d3 transition states in between reactive runs. \"\"\" htl \"\"\" script src \"https cdn.jsdelivr.net npm d3 6.2.0 dist d3.min.js\" script script id \"hello\" const positions dot positions const svg this null ? DOM.svg 600,200 this const s this null ? d3.select svg this.s s.selectAll \"circle\" .data positions .join \"circle\" .transition .duration 300 .attr \"cx\", d d .attr \"cy\", 100 .attr \"r\", 10 .attr \"fill\", \"gray\" const output svg output.s s return output script \"\"\" details \"Show with syntax highlighting\", md\"\"\" ```htmlmixed script src \"https cdn.jsdelivr.net npm d3 6.2.0 dist d3.min.js\" script script id \"hello\" const positions dot positions const svg this null ? DOM.svg 600,200 this const s this null ? d3.select svg this.s s.selectAll \"circle\" .data positions .join \"circle\" .transition .duration 300 .attr \"cx\", d d .attr \"cy\", 100 .attr \"r\", 10 .attr \"fill\", \"gray\" const output svg output.s s return output script ``` \"\"\" md\"\"\" Example Preact with persistent state \"\"\" md\"\"\" Modify `x`, add and remove elements, and notice that preact maintains its state. \"\"\" x \"hello pluto \", 232000,2,2,12 ,12,2,21,1,2, 120000 details md\"\"\" ```htmlmixed script type \"module\" id \"asdf\" await new Promise r setTimeout r, 1000 const html, render, Component, useEffect, useLayoutEffect, useState, useRef, useMemo, createContext, useContext, await import \"https cdn.jsdelivr.net npm htm 3.0.4 preact standalone.mjs\" const node this ?? document.createElement \"div\" const new state state if this null PREACT APP STARTS HERE const Item value const loading, set loading useState true useEffect set loading true const handle setTimeout set loading false , 1000 return clearTimeout handle , value return html` li \\ loading ? html` em Loading... em ` value li ` const App const state, set state useState new state node.set app state set state return html` h5 Hello world h5 ul \\ state.x.map x,i html` \\ Item value \\ x key \\ i ` ul ` PREACT APP ENDS HERE render html` \\ App `, node else node.set app state new state return node script ``` \"\"\", \"Show with syntax highlighting\" state Dict x x htl \"\"\" script id \"asdf\" await new Promise r setTimeout r, 1000 const html, render, Component, useEffect, useLayoutEffect, useState, useRef, useMemo, createContext, useContext, await import \"https cdn.jsdelivr.net npm htm 3.0.4 preact standalone.mjs\" const node this ?? document.createElement \"div\" const new state state if this null PREACT APP STARTS HERE const Item value const loading, set loading useState true useEffect set loading true const handle setTimeout set loading false , 1000 return clearTimeout handle , value return html` li \\ loading ? html` em Loading... em ` value li ` const App const state, set state useState new state node.set app state set state return html` h5 Hello world h5 ul \\ state.x.map x,i html` \\ Item value \\ x key \\ i ` ul ` PREACT APP ENDS HERE render html` \\ App `, node else node.set app state new state return node script \"\"\" html\" span id getBoundElementValueLikePluto span span id setBoundElementValueLikePluto span span id getBoundElementEventNameLikePluto span \" md\"\"\" Bond internals `getBoundElementValueLikePluto`, `setBoundElementValueLikePluto`, `getBoundElementEventNameLikePluto` Okay this one is not so exciting, but when you use ` bind` ```julia bind x html \" some element some element \" ``` Then Pluto will subscribe to the `\"input\"` event of ` some element `, and take its `.value` property to bind to the Julia variable. Well... almost For some elements, the event name and value getting is different. E.g. with ` button `, we actually listen to `\"click\"` instead of `\"input\"`. And for ` input type range `, we get the `.valueAsNumber` property instead of `.value`. This is what you can use these functions for ```ts getBoundElementValueLikePluto element HTMLElement any setBoundElementValueLikePluto element HTMLElement, value any void getBoundElementEventNameLikePluto element HTMLElement string ``` They can be useful when creating higher order widgets widgets that layer on top of, or interact with other widgets. \"\"\" html\"\"\" span id metadata span span id getNotebookMetadataExperimental span span id setNotebookMetadataExperimental span span id deleteNotebookMetadataExperimental span span id getCellMetadataExperimental span span id setCellMetadataExperimental span span id deleteCellMetadataExperimental span \"\"\" md\"\"\" Metadata for notebooks and cells Notebooks can have metadata, which is stored as TOML content at the top of the `.jl` file. For example, frontmatter https github.com JuliaPluto Pluto.jl pull 2104 is stored as notebook metadata. We have some experimental API that lets you work with notebook metadata from widgets This could be a very powerful feature when used well Note that you can also use sessionStorage localStorage https javascript.info localstorage inside your widgets. Think about what your storage should be persisted for `sessionStorage` reading a notebook, running and changing cells. But when opening the notebook tomorrow, it should be gone. `localStorage` stored for a long time on this browser. Will be there tomorrow, but someone else opening the notebook will not have the data. notebook cell metadata stored permanently in the `.jl` file when someone else opens the notebook, they will continue with your storage. For this, we provide the following API ```ts getNotebookMetadataExperimental key string any setNotebookMetadataExperimental key string, value any Promise void deleteNotebookMetadataExperimental key string Promise void ``` The objects that you store should be TOML serializable stick to simple JS types like String, Number, Array, Object. Return type `Promise void ` means that a promise is returned, that resolves when the data is stored correctly. Cell metadata ```ts getCellMetadataExperimental key string, cell id string? any setCellMetadataExperimental key string, value any, cell id string? Promise void deleteCellMetadataExperimental key string, cell id string? Promise void ``` Providing the `cell id` is only necessary when storing data on another cell than that where your ` script ` is executing. Return type `Promise void ` means that a promise is returned, that resolves when the data is stored correctly. \"\"\" TableOfContents "},{"url":"en/docs/keyboard-shortcuts/","title":"⌨️ Keyboard shortcuts","description":"Overview of keyboard shortcuts in Pluto's editor","tags":["docs","editor"],"text":"Keyboard shortcutsThis page lists the default keyboard shortcuts in Pluto. The keys shown below adapt to your system (Windows, Mac, Linux).Running cellsShiftEnterRun cellEnterRun cell and add cell belowSSubmit all changesQInterrupt notebookEditingTab / ShiftTabIndent / outdent\\Auto indentTab or Space or IShow autocompleteMToggle markdown/Toggle commentDSelect word / next occurrenceShiftDUnselect previous occurrenceL\n        or\n        LSelect lineKDelete lineIExpand selection\\Jump to matching bracketclickAdd cursorCell actionsDelete or BackspaceDelete empty cell↑Move line/cell up↓Move line/cell downclickJump to definition[Hide cell code]Show cell codeClipboardCCopy selected cellsXCut selected cellsVPaste selected cellsNavigationPage Up / fn↑Jump to cell abovePage Down / fn↓Jump to cell belowHelpF1 or ?Show keyboard help\n    /* Keyboard shortcuts table styles */\n.keyboard-shortcuts th:first-child {\n    text-align: center;\n}\n\n.keyboard-shortcuts td:first-child {\n    text-align: right;\n}\n\n    .keyboard-shortcuts th.keyboard-shortcut-section {\n        background: hsl(268.46deg 45.95% 47.7% / 14%);\n        text-align: left;\n        border-radius: 0.5rem;\n    }\nView this list in PlutoPress F1 or ? in Pluto to see a pop-up with the most important tips.\nAdditionally, Pluto supports handy multi-select features: press Tab for multiple cursors, or hold  to make clean rectangular selections.Navigating between cellsYou can navigate between cell inputs using the arrow keys: when your cursor is at the beginning or end of a cell, you can use additional arrow key presses to navigate to the next or previous cell.You can also use fn↑ and fn↓ (on Mac) or Page Up and Page Down to jump between cells directly.Keyboard-only navigationPluto can be used in keyboard-only mode, using tabbing navigation. Use Tab to move focus to the next element. Inside the code editor press Esc first, then Tab, because Tab alone indents your code. Use ShiftTab to move focus back.Keyboard-only navigation is important for accessibility, so if you find a UI element that has poor keyboard access, please let us know!\nconst isMac = /Mac/i.test(navigator.userAgentData?.platform ?? navigator.platform);\nconst controlName = isMac ? \"⌃\" : \"Ctrl\"; // ⌃\nconst ctrlOrCmd = isMac ? \"⌘\" : \"Ctrl\";  // ⌘\nconst altName = isMac ? \"⌥\" : \"Alt\";     // ⌥\nconst and = isMac ? \" \" : \"+\";\nconst foldPrefix = isMac ? `${altName}${and}${ctrlOrCmd}` : `Ctrl${and}Shift`;\nfor (const el of document.querySelectorAll('.control-name')) el.textContent = controlName;\nfor (const el of document.querySelectorAll('.ctrl-or-cmd')) el.textContent = ctrlOrCmd;\nfor (const el of document.querySelectorAll('.alt-name')) el.textContent = altName;\nfor (const el of document.querySelectorAll('.and')) el.textContent = and;\nfor (const el of document.querySelectorAll('.fold-prefix')) el.textContent = foldPrefix;"},{"url":"en/docs/language/","title":"🌐 Language","description":"How to change the language of Pluto","tags":["docs","localization","navigation"],"text":"LanguagePluto can be used in multiple languages. You can change the language of Pluto by opening a notebook, and selecting a language in the bottom left of the interface.The percentage shown next to the language name shows how much of the Pluto interface is localized. Some (new) features might not be localized yet, they will be displayed in English.Currently, Pluto is available in the following languages (in alphabetical order):العربية (Arabic) (by @ariguiba)Chinese (Chinese) (by @Fromduststar)Dansk (Danish) (by @gwr-de)Deutsch (German) (by @kellertuer)Ελληνικά (Greek) (by @pankgeorg)EnglishEspañol Latinoamericano (Latin American Spanish) (by @gruumsh1)Corporate English (💼🗄️👔) (by @pankgeorg)Français (French) (by @Pangoraw and @gdalle)Čeština (Czech) (by @kunzaatko)Italiano (Italian) (by @disberd)Japanese (Japanese) (by @Itou-Kouki)Nederlands (Dutch) (by @fonsp)Norsk Bokmål (Norwegian) (by @kellertuer)فارسی (Persian) (by @shosseinib)Polski (Polish) (by @s-zymon)Português (Portugal) (Portuguese Portuguese) (by @rgouveiamendes)Suomi (Finnish) (by @eteppo)Example: Pluto in GreekExample of the Pluto interface in Greek. Notice that interface elements are translated, but the featured notebook is still in English.What is not localized?Selecting the language will localize the Pluto interface (button names, warning messages, etc from Pluto). This setting does not affect:The notebook content (code, markdown, etc). You can write in any language you want!\nOne exception: Julia keywords like function, if, for, etc are always in English.Error messages (these are always in English)Documentation (this is always in English)We also don’t localize number formats. Numbers are always formatted in Julia style (e.g. 1.5 for 3 / 2, not 1,5).Automatic translation supportPluto notebook content (notably: markdown) can be translated automatically when reading a notebook. You can use a service that translates complete websites (like the Chrome Translate feature) when reading a notebook. This will translate cell outputs (like markdown cells), but not cell inputs (code), because code might become hard to interpret when translated. Pluto uses the translate HTML attribute to mark which content should be translated.If you have any feedback on this feature, please let us know! You can open an issue, or get in touch another way.ContributingWould you like to help make Pluto available in more languages?We want to make Pluto and Julia more accessible to a wider audience! Since 0.20.14 (August 2025), Pluto has a localization system, which means that the Pluto UI interface can be used in a different language (English, Greek, etc). Because the Pluto developers only speak a couple of languages, we rely on contributions from the community to make Pluto available in more languages!Localizing Pluto is a great way to help the Julia community, because it makes Julia more accessible to a much wider audience. Pluto is used around the world, but Julia and Pluto are still hard to use for people who don’t speak English.We also want to break the tradition that “programming is in English”. Programming is for everyone, and we hope that computers can be used regardless of language and culture.Your work is also an open source contribution! Because you contribute localizations via git and github, you will be listed in the Pluto contributors list (the section “Contributors” on the Pluto.jl repository GitHub page), and in the Pluto release notes.CollaborationThe Pluto developers are really grateful for your help in localizing Pluto! 🌟 And we are super excited to collaborate with you!The ability to localize Pluto is quite new, and there will still be rough edges. Feel free to reach out whenever you want, and we will try to help you quickly! You can email us, open an issue, open a draft PR, whatever you prefer!We are really interested in a right-to-left language (like Arabic or Farsi). This might require some additional tweaking, so reach out if you are interested to contribute, and we can work together to support it!How to contributeTake a look at our localization documentation to get started! We look forward to your contributions! 💛"},{"url":"en/docs/latex/","title":"🧮 LaTeX","description":"How to use LaTeX in Pluto","tags":["docs","writing","latex","markdown"],"text":" A Pluto.jl notebook v0.20.23 frontmatter order \"4\" title \"🧮 LaTeX\" date \"2025 08 01\" tags \"docs\", \"writing\", \"latex\", \"markdown\" description \"How to use LaTeX in Pluto\" layout \"layout.jlhtml\" using Markdown using InteractiveUtils md\"\"\" LaTeX in Pluto Pluto has built in support for LaTeX math equations. You use can use LaTeX inside Markdown .. markdown blocks. There are two ways to write LaTeX, we recommend the following method Inline math To write a math equation inline , use the double backticks around the equation \"\"\" md\"\"\" Here is an inline equation ``\\frac 1 2 \\pi ``. \"\"\" md\"\"\" Block math To write a large block equation , use triple backticks with `math` this is a code block with `math` as the language \"\"\" md\"\"\" Finding LaTeX Syntax If you don't know the LaTeX syntax for a symbol, you can use the Live Docs to look it up just type the Unicode character and see its LaTeX equivalent. You can also use this to find the name of emojis \"\"\" md\"\"\" Example of Reverse Search for Integral Symbol https github.com JuliaPluto website blob 6cad65a4b0f3969b758c8b80c40623ea8dc04429 src assets img live docs latex search.png?raw true \"\"\" md\"\"\" Here is a block equation ```math \\frac 1 2 \\pi ``` \"\"\" md\"\"\" Old syntax Julia Markdown also has another way to write LaTeX, using the ` ` dollar sign. However, because it can conflict with string interpolation https docs.julialang.org en v1 manual strings string interpolation in confusing ways, we recommend using the backtick method described above instead. \"\"\" md\"\"\" Inline math ⚠️ old syntax Here is how to write inline math with ` `. \"\"\" md\"\"\" Here is an inline equation \\frac 1 2 \\pi . \"\"\" md\"\"\" Block math ⚠️ old syntax Here is how to write block math with ` `. The syntax is the same, but Markdown uses block math if the math equation is the only content of a line. \"\"\" md\"\"\" Here is a block equation \\frac 1 2 \\pi \"\"\" md\"\"\" tip Instead of using the old ` ` syntax, we recommend using backticks instead. See the section above. \"\"\" md\"\"\" Emojis in Pluto Pluto has built in support for Emojis. You use can them inside Markdown .. markdown blocks. To find the emoji or symbol you need, start with `\\` and type the name of the emoji, some suggestions will be made, so you can find the correct emoji for you. \"\"\" md\"\"\" Example of Emoji Auto fill https github.com JuliaPluto website blob ce4f61d72a6fc804ae00dd73ea7c382dbfc78e09 src assets img dog emoji.png?raw true \"\"\" md\"You can only use emojis to define some variables \" 🐶 1 🐱 1 🏠 🐶 3 🐱 "},{"url":"en/docs/launch-pluto/","title":"🌟 Launching Pluto","description":"How to start a Pluto notebook server","tags":["docs","file","navigation"],"text":"How to start PlutoPluto is a Julia package, which runs on your computer. It start a small local web server, and you can connect to it from your web browser.Step 0: install Julia and PlutoDid you already install Julia and Pluto? Take a look at the installation guide.Step 1: start JuliaFirst, start Julia. In some cases, you can search for the app “Julia” on your computer and launch it. In other cases, you can open a terminal (search for the app “Terminal”) and type the command julia.Step 2: start PlutoIn Julia, run this command to start Pluto:import Pluto\nPluto.run()\nBrowser sessionWhen Pluto starts running, it automatically opens a new browser tab that connects to http://localhost:1234/, which is the address of the Pluto server. You will see the main menu of Pluto.The Pluto main menuThe first page you see when you open a new browser tab is the main menu of Pluto. It’s the page that says “Welcome to Pluto”. From here, you can create a new notebook, open an existing notebook, or you can take a look at the featured notebooks, further down the page.Go to the main menu from a notebookTo go back to the main menu from a notebook, you can click the Pluto logo in the top left corner of the browser window.TipJust like on websites, you can open pages in a new tab. For example, you can right click the Pluto logo in the top left corner of the browser window, and select “Open in new tab”. This will open a new tab that is connected to the same Pluto session.Go to the main menu from a new tabIf you open a new tab in your browser, you can also go directly to the Pluto server. Type localhost:1234 in the address bar, and press Enter. You can also bookmark this page for easy access.Multiple notebooksSomething important to know: each Pluto session (created by running Pluto.run()) can run multiple notebooks at the same time. The notebooks in your Pluto session are managed from the Pluto main menu. In the screenshot above, you see the Pluto main menu, with 3 notebooks currently running.If you use the main menu to create a new notebook or open a notebook, it will be added to the session. If you go back to the main menu, you can add more notebooks to the session.How to stop PlutoTo stop Pluto, you can press Ctrl+C in the terminal where you started Pluto. You might need to press Ctrl+C multiple times. This will stop the Pluto server, and all notebooks in the session will shut down.Advanced: Mirror viewPluto has a special feature – you can open the same notebook in two different browser windows, and they will stay synchronized. This is useful if you are working with two parts of a notebook at the same time. For example, you can change your analysis code (at the bottom of the notebook) in one window, and you can watch the plots (at the top of the notebook) in a second window.To use mirror view, you first open a notebook, and you copy the URL of the notebook from the address bar. This will look like http://localhost:1234/edit?id=0ec9caa2-3fa7-11f0-3e46-3bcef32ce8e3. Then open a new browser window, and paste the URL in the address bar. Now you have two windows that are connected to the same notebook, and they will stay synchronized.Limitation: no unsaved editsCurrently, unsaved edits (code changes before your press Shift+Enter or Save) are not synced between the two windows. This is usually not an issue, but it is possible to lose work if both sides are editing the same cell – submitting on one side will overwrite the other side. The other side can still use Ctrl+Z to get their old code back. See this PR for more detailsTipYou can also use the “Mirror view” feature to collaborate with someone else on another computer, which can be really fun! We recommend a service like bore.pub to share the notebook with someone else, and don’t change Pluto’s security settings. Because – be careful! Someone with access to the notebook, has complete access to your computer. They can install and run programs without your approval.We have used this feature to collaborate on notebooks, and we found it quite important to have good communication using an audio call. This also avoids editing the same cell.Advanced: Multiple Pluto sessionsYou can start Pluto multiple times in parallel (for example: on two different Julia versions). In this case, each Pluto server will find the first available port. Usually, the first server will find port 1234, the second server will find port 1235, and so on.This means that you can open two browser windows, and connect to the two different Pluto servers in parallel:http://localhost:1234/\nhttp://localhost:1235/\nUsually, this is not super useful. If you find yourself on port 1235 by accident, try shutting down all Pluto/Julia processes and starting again.Advanced: Remote access with SSHIf the server (where Pluto will run) and the client (the machine whose browser will use Pluto) are on the same network then set the host to 0.0.0.0 while launching Pluto (e.g Pluto.run(host=\"0.0.0.0\")). An example use case is if you have a headless raspberry pi and a laptop connected to the same wi-fi network in your home. You can run Pluto on the raspberry-pi and use your laptop’s browser for development.However, if the server is remote and has a public ip you need to set up an SSH tunnel. First, log in to your server using SSH and start a Pluto server. Then open a local terminal on your own computer and type:ssh user@ipaddress -N -L 1234:localhost:1234\nwith user and ipaddress filled in accordingly. You can then go to http://localhost:1234/ on your own computer to get started! For more info and instructions for Windows, see this guide. This can come in handy if your server is on a cloud service such as AWS or Azure. The latter method can be used in the former case too provided an ssh client is available and enabled on both machines."},{"url":"en/docs/lectures/","title":"🧑‍🏫 Lectures","description":"How to use Pluto to teach Julia with interactive lectures.","tags":["docs","education"],"text":"Pluto for lecturesPluto is great for writing lectures in the “Pluto style”. This means lectures with:A modern look – lectures with simple markdown and plots should look great, with modern typography and design, on desktops, mobile phones and PDF.Interactive content – sliders, scrubbable numbers, buttons and more, to control outputs like plots, numbers and tables.Reproducibility – Pluto notebooks are easy to share, and anyone can open a notebook and run it themself.Easy to useAnd our goal is to make this as easy as possible to set up and use. This is how we do that:A modern look – Pluto is built on “smart defaults”. Instead of endless themes and settings pages, we have one modern design that is designed to look best on today’s web. We find that students appreciate a modern-looking tool!Interactive content – Pluto uses reactivity to make everything interactive. We believe that reactive global variables are the most accessible way to make notebooks interactive. Interactive UI (sliders) works using the same mechanism (reactive globals), which means that anyone can learn how to use it. Pluto is not the most advanced interactivity tool for Julia, but it is the easiest to learn.Reproducibility – using reactivity, a built-in package manager, binder and more, we try our best to make sure that Pluto notebooks are reproducible by default. Our hope is to make Julia notebooks just like Powerpoint, Photoshop and Excel files – you can open them, and they will work.ExamplesTo see examples of interactive lectures, take a look at the featured notebooks.Lecture notes onlineYour notebooks are stored as .jl Julia files, but Pluto makes it easy to distribute your lecture notes in formats that are easily readable by students. You can export to HTML files (recommended) which look great on any device (mobile and desktop), or you can generate PDF files.You can also generate HTML files automatically using GitHub Actions (or similar), and turn your git repository into a website automatically. This is ideal for courses under development, with multiple contributors.Learn more about lecture notes online"},{"url":"en/docs/linking/","title":"🔗 Linking","description":"How to link to other pages in Pluto.","tags":["docs","writing","linking","link","href","reference","section"],"text":"Linking to sectionsYou can use # in a URL to link to a specific section of a Pluto notebook. You can link to:global variables with #variable_namefunction definitions with #function_nameMarkdown headers with #header-text(see below for instructions)Within a notebookYou can use Markdown hyperlinks to link to a different section of the same notebook. For example, if you define a variable fruits = [\"apple\", \"pear\"] at the top of your notebook, then you can link to it with:md\"\"\"\nTake a look at [the fruits variable](#fruits).\n\"\"\"\nClicking on the link will jump straight to the definition of fruits.A section in a notebook onlineYou can also link to a specific section of a notebook online. For example, if your notebook is hosted at:https://pluto.land/n/lp7p4qk7Then I can link to sections by adding the # hash to the URL. For example, to link to the example_step variable:https://pluto.land/n/lp7p4qk7#example_stepOr I can link to the header “Adding color”:https://pluto.land/n/lp7p4qk7#Adding-colorLinking to variables and functionsAll global variables (and functions, types, etc.) are automatically linkable in Pluto notebooks. The variable name is the link text.TipYou can use this to make items linkable! For example, if you want to link to a plot (which usually has no id), you can add a “dummy variable” my_plot = 123 inside the cell that creates the plot, and then link to it with #my_plot.Linking to Markdown headersWhen you hover over a Markdown header, you can click the 🔗 button to copy the header id to your clipboard. This will copy a string like #Adding-color to your clipboard, which you can then paste somewhere to use as URL.When you are reading a notebook online (instead of editing on localhost), the button will copy not just the header id, but the full URL to the header, like https://pluto.land/n/lp7p4qk7#Adding-color.InfoThis feature is only available in Pluto 0.20.13 and later."},{"url":"en/docs/live-docs/","title":"📚 Live Docs","description":"The Live Docs tab in Pluto to read documentation while you code!","tags":["docs","editor","live-docs","docs"],"text":"Live DocsThe Live Docs tab in Pluto lets you read documentation while you code. Julia has a built-in documentation system, which lets Pluto query the documentation of any Julia object.Documentation while you typeWhile you are typing code, or when you select some text, Live Docs will automatically start searching for documentation. This means that you can just leave the window open, and it will quietly search documentation while you work. Whenever you need to know how a function works, just take a look at the Live Docs tab.You can also search for documentation directly, by typing something into the search box."},{"url":"en/docs/logging/","title":"🧾 Logging","description":"How to log in Pluto","tags":["docs","editor","logging"],"text":"Logging and stdoutTo help with debugging your code, Pluto supports showing messages printed with the standard library Logging module. This can be done using the @info, @warn and @error macro.For example, you can use @info somewhere in your code to see the value of a variable while your code runs:begin\n\tresult = 0\n\t\n\tfor i in 1:5\n\t\tx = i^2\n\t\t@info(\"Current value\", x)\n\t\tresult += x\n\tend\n\tresult\nend\nYou can give @info as many arguments as you want. The first argument is a message, and the other arguments are key-value pairs that will be shown in the logs. For example, we can add i to the log.Log levels: @debug, @info, @warn, @errorEach log message can have a level or severity. This makes it easy to distinguish between different types of log messages. To change the log level, you can use the corresponding macro: @debug, @warn or @error instead of @info.@debug is useful when sharing your work as a package. @debug logs will only display in your notebook, but not when someone else imports your code/package.Special log argumentsPluto will use its rich object inspector to display the arguments of log messages. This means that you can log complex objects like Dicts, DataFrames, or even plots, and they will be displayed in a nice way in the logs.Here is an example of logging a Vector, and an Exception:Hiding logs for a cellIf a package logs warnings or info messages that you want to hide (especially in the static export of the notebook), then the option to hide logs can be toggled by clicking on the cell menu (the three dots on the right).To filter logs more specifically, you can use a package like LoggingExtras.jl.Logging progressPluto supports an integration with the ProgressLogging.jl package which can be used to display a progress bar in the log message area:Writing to standard outputYou can also use Julia functions like println, display, @show or show, which will write information to the standard output stream. This is the “old” way of logging information, but it is still supported in Pluto in case you need it.Use Logging instead of stdout!We recommend using Logging instead of println. There are many advantages of using Logging instead of writing to standard output:Logging works when writing multi-threaded code. println will mix different threads’ output together, making it unreadable.Logging allows for more structured information. For example, you can log a Dict and inspect it in Pluto. You can even log plot(data) and see the plot!Logging can be easily filtered/disabled by the caller of a function. This is useful when writing packages. It can improve the experience and performance of your package.Disable capturing of standard outputBy default, Pluto captures the standard output stream and shows it in the notebook. To disable this, and show it inside the terminal instead, the capture_stdout=false option can be provided to Pluto.run when launching Pluto. Learn more about configuring Pluto."},{"url":"en/docs/markdown/","title":"📝 Markdown","description":"How to write markdown in Pluto.","tags":["docs","writing","markdown","md","markdown","text","writing"],"text":"Markdown in PlutoMarkdown is the easiest way to write text in Pluto notebooks. With Markdown, you can write text with bold, italic, and other formatting, and you can use it to add titles, lists, images, and more.You use markdown with the md\"\"\" string macro inside a Pluto cell:md\"\"\"\nThis text is in **bold** and _italic_.\n\"\"\"\nThis is what that looks like in the notebook:Complete guideRead more about Markdown in Pluto here:Loading...How use Markdown in Pluto →\n\tconst notebook_html_url = \"https://featured.plutojl.org/basic/markdown\"\n\tconst white_svg_uri = \"data:image/svg+xml;utf8,<\\svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect width='100%' height='100%' fill='ivory'/><\\/svg>\"\n\n\tfetch(notebook_html_url).then(r => r.text()).catch(e => \"\").then(html_data => {\n\t\tconst doc = new DOMParser().parseFromString(html_data, \"text/html\");\n\t\tconst head = doc.head\n\n\t\tconsole.log({doc, notebook_html_url})\n\t\tconst q = sel => currentScript.parentElement.querySelector(\".pe-card\").querySelector(sel)\n\n\t\tq(\"a img\").src = head.querySelector('meta[property=\"og:image\"]')?.content ??\n\t\t\twhite_svg_uri\n\t\t\n\t\tq(\".pe-about h2\").innerText = (doc.title == \"\" ? null : doc.title) ?? \n\t\t\tnew URL(notebook_html_url).pathname.split(\"/\").map(decodeURIComponent).toReversed().find(s => s) ??\n\t\t\t\"Notebook\"\n\t\t\n\t\tq(\".pe-about p\").innerText = head.querySelector('meta[name=\"description\"]')?.content ?? \n\t\t\t\"\"\n\t})\n\n\n\t.pe-container {\n\t\tcontainer-type: inline-size;\n\t}\n\t\n\t.pe-card {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tmax-width: 700px;\n\n\t\tborder-radius: 6px;\n\t\tbackground: salmon;\n\t\tbackground: linear-gradient(80deg, #e9dbe3, #ffdabe);\n\t\tpadding: 10px;\n\t\tgap: 20px;\n\t\tmargin: 10px 0;\n\t\tbox-shadow: 0 2px 10px rgb(0 0 0 / 14%);\n\t}\n\n\t@container (max-width: 400px) {\n\t\t.pe-card {\n\t\t\tflex-direction: column;\n\t\t\tgap: 0;\n\t\t}\n\t\t.pe-about {\n\t\t\tmargin: 0 10px 10px 10px;\n\t\t}\n\t}\n\n\t.pe-card > a {\n\t\toverflow: hidden;\n\t\tborder-radius: 5px;\n\n\t\tflex: 0 0 35%;\n\t\taspect-ratio: 3 / 2;\n\t}\n\t\n\t.pe-card > a > img {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\t\n\t\tobject-fit: cover;\n\t}\n\n\tdiv.pe-about :is(p, h2) {\n\t\tcolor: black;\n\t\ttext-decoration: none;\n\t\tborder-bottom: none;\n\t\tmargin-block-end: 0;\n\t}\n\n\t.pe-right {\n\t\tflex: 1 1 auto;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: space-between;\n\t}\n\n\t.pe-nav {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.pe-nav a {\n\t\ttext-decoration: none;\n\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Cantarell, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n\t\"Segoe UI Symbol\", system-ui, sans-serif;\n\t\tfont-weight: 700;\n\t\tbackground: white;\n\t\tcolor: black;\n\t\tpadding: 8px 14px;\n\t\tborder-radius: 1000px;\n\t}\nKeyboard shortcutWhen editing a cell, you can press Cmd+M or Ctrl+M to automatically add or remove the md\"\"\" string macro.Julia cells and Markdown cellsSome notebook environments have different cell types: a code cell and a Markdown cell. In Pluto, there is only one cell type: a Julia cell. But you can use the Julia string macro md\" to write Markdown inside of Julia! 🤯Markdown syntaxThe library that provides the md\" macro is the Julia standard library (stdlib) Markdown. This library might work a bit differently from the Markdown that you are used to in GitHub, Jupyter, or elsewhere.Other Markdown librariesThe Markdown stdlib is usinged by default in Pluto, but you are free to use other Markdown libraries. You can also use something other than Markdown, like HTML (with HypertextLiteral.jl).Some other Markdown libraries that you can use in Pluto:CommonMark.jlMarkdownLiteral.jl"},{"url":"en/docs/moving-cells/","title":"🔃 Selecting and moving cells","description":"How to move cells in Pluto","tags":["docs","editor"],"text":"Moving a single cellPluto allows you to place your cells in any order. You can do this by dragging the cell from the left shoulder. A bold line shows where the cell will be moved to.TipPluto’s reactivity means that you can put cells in any order, and they will still execute correctly based on the dependencies between cells. This means that you can place cells in the order that makes the most sense for your story, which is not always the order that makes the most sense for the computer. And if you accidentally create a cyclic dependency between your variables, Pluto will detect it and notify you.For example, you can first tell your story using Markdown cells and plots, and then add a section # Appendix with package imports, helper functions and more.Selecting cellsYou can select multiple cells, which is useful for moving them together. To select cells, click between two cells and drag to make a selection.Selecting cells on wide screensIf your window is wide enough, you can also use the right margin to start a selection:Moving multiple cellsYou can move multiple cells by Selecting multiple cells and then dragging one of them.Copying cellsIf you press Ctrl+C (or CmdC on Mac) while cells are selected, you can copy them to the clipboard. You can paste these cells in a notebook, or as plain text in another application.More actionsWhile multiple cells are selected, you can apply various actions to them simultaneously: moving, copying, deleting, folding and un-folding.Moving between notebooksYou can also move cells between different notebooks. To do this, open two notebooks in two different windows, and place them side-by-side. You can now drag cells between the two notebooks, and they will be copied to the other notebook."},{"url":"en/docs/notebooks-online/","title":"📕 Notebooks online – Pluto.jl notebooks as web pages","description":"How to turn Pluto.jl Julia notebooks into web pages by hosting them on a website. How to make them interactive with PlutoSliderServer.","tags":["docs","publishing","PlutoSliderServer","glass","glassnotebook","github","hosting","web","export","html","netlify"],"text":"How to host Pluto.jl notebooks onlineWhen you are done writing your notebook, you can put it on the internet as a website! Notebooks as websites is a core feature of Pluto. This page will explain how you go from a notebook on your computer, say animals.jl, to a website like https://example.com/animals, where anyone can read your notebook directly, without needing to install Julia or Pluto.There are many options fitting to different needs. Some are really easy, while others are more complex.📎 Pluto file formatsAnd good to know: Pluto notebooks are .jl files, which only contain the code of your notebook, not the outputs. For example, if your notebook contains plot(x, y), then the resulting PNG image is not stored in the .jl file. Other people need to install Pluto to open the file.You can also use Pluto to export a notebook to a .html or .pdf file by clicking the  icon. These files contain outputs, like the plot image. Other people can open these files directly on their computer, without needing to install Pluto.pluto.land: Simple sharingpluto.land is a new, simple way to share your Pluto notebooks online. You can upload HTML export files, or export directly from Pluto. You’ll get a unique URL that you can share with anyone!Pros:AwesomeSuper simple to useNo account requiredDeveloped and maintained by the Pluto teamCons:No changes after upload: to change the notebook, you upload a new HTML file, and you get a new URLGitHub: static-export-templateIf you have a GitHub account, then this is the easiest option. Go to github.com/JuliaPluto/static-export-template and follow the easy instructions with screenshots to set up your repository. This sets up a repository with .jl notebook files, which are automatically executed, exported and hosted on the cloud. You get a website like https://username.github.io/my_project where you can read the notebooks.Pros:FreeWorks for multiple notebooksEasy notebook updates: changing .jl files automatically updates the websiteCons:Takes 15-30 minutes to set up (but not too hard!)You need to use GitHubGitHub: computational-thinking-templateThis is a more advanced option for courses that want an attractive website with landing page, sidebar, search, and more. We have developed the GitHub repository template JuliaPluto/computational-thinking-template, which you can use to create a course website based on the Computational Thinking course at MIT, developed by Fons.PlutoPages.jl – build your own sitePlutoPages.jl is a static site generated with support for stacked layouts, search, frontmatter, caching, mixed content (Markdown, HTML, Pluto) to generate a professional-grade static website. PlutoPages is inspired by Eleventy.This tool is more difficult to set up and maintain than the simple static-export-template, but it lets you create complete websites, not just a collection of notebooks.Learn moreNetlify drop: “easy for folders”If you just have a couple of .html files that you exported with Pluto, then you can use netlify drop to put them online as a website. Put all .html files in one folder on your computer, and drag the folder into netlify drop. This will give you a website!This only works with .html files that you exported yourself, not with .jl notebook files.Pros:FreeFast and easyCons:Updating the website with new notebooks requires a bit of careYou need a Netlify accountNo automatic index page listing all notebooksDeprecatedThe options below used to work in the past, but they are no longer supported.Glass Notebook (deprecated)If you have a GitHub account, then glassnotebook.io is a great option for hosting your notebooks online. Glass can also host notebooks interactively: people who visit your website can interact with sliders and buttons instantly! Glass was made specifically for Pluto.jl, so it works great with Julia and Pluto!Pros:Free (for static notebooks)Ability to host interactive notebooks (paid option)Easy user interfaceSupport from developers if things don’t workCons:You need to use GitHub"},{"url":"en/docs/packages-advanced/","title":"📦 Packages: advanced – Pkg.activate in a cell","description":"How to use Pkg.activate in Pluto.jl notebooks to set up a custom Pkg environment.","tags":["docs","reproducibility","advanced"],"text":"Advanced: set up an environment with Pkg.activatePluto’s package manager is enabled for all users, for ease of use and to promote reproducibility in scientific computing. There is no option to disable the behaviour globally (for your entire Pluto session). Instead, Pluto will detect notebooks that use Pkg.activate to set up an environment explicitly, and uses the old behaviour for those notebooks.The philosophy here is that everyone should have a reproducible package environment by default, without having to do anything. This takes priority over other use cases, and hence not using the built-in package manager requires some extra work.Any notebook that calls Pkg.activate will not use Pluto’s package management, and run in ‘backwards compatibility mode’. The Pkg.activate call should be placed directly in your notebook code: it is detecting using the same syntax analysis used for reactivity.Pattern: The “global environment”If you do not intend on sharing a notebook file and you want to use your global package environment (called (v1.10) or similar, the one you get when you launch the Julia REPL), then you can call Pkg.activate() without any arguments.🙋 If you are developing a package, then activating your global environment is an easy way to test your local version in Pluto.This “global environment” pattern can be placed at the top of a notebook:begin\n    import Pkg\n    # careful: this is _not_ a reproducible environment\n    # activate the global environment\n    Pkg.activate()\n    using Plots, PlutoUI, LinearAlgebra\nend\nWhen running this in Pluto (try it out!), you will notice that the status marks next to packages disappear, and Pluto is running in ‘backwards compatibility mode’. Packages will no longer be installed or removed automatically, you have to use the Pkg REPL to do this yourself.Pattern: The “shared environment”If you have multiple notebooks in a repository and you want to use share a Pkg environment between them, then you can call Pkg.activate(path_to_environment). You can use @__DIR__ to get the path of the notebook’s folder, and joinpath(@__DIR__, \"..\") to get its parent, joinpath(@__DIR__, \"..\", \"..\") for the parent’s parent, etc.The function Base.current_project() can be used to automatically find the closest parent directory that contains a Project.toml, in most cases this is what you want.For example, if your project looks like this:my_project/\n    data/\n        ...\n    notebooks/\n        Interesting analysis.jl\n        ...\n    Project.toml\n    Manifest.toml\n    ...\nthen the “shared environment” pattern can be placed at the top of a notebook:begin\n    import Pkg\n    # activate the shared project environment\n    Pkg.activate(Base.current_project())\n    # instantiate, i.e. make sure that all packages are downloaded\n    Pkg.instantiate()\n    using Plots, PlutoUI, LinearAlgebra\nend\nWhen running this in Pluto, you will notice that the status marks next to packages disappear, and Pluto is running in ‘backwards compatibility mode’. Packages will no longer be installed or removed automatically, you have to use the Pkg REPL to do this yourself.Pattern: The “Pkg cell”When adding packages, Pluto’s default package management will always install the latest version from the registry. If you need to install a specific version or branch of a package, or a package is not registered, you can use a “Pkg cell”.A common pattern is a so-called “Pkg cell”, placed at the top of a notebook:begin\n    import Pkg\n    # activate a temporary environment\n    Pkg.activate(mktempdir())\n    Pkg.add([\n        Pkg.PackageSpec(name=\"Plots\", version=\"1\"),\n        Pkg.PackageSpec(name=\"PlutoUI\", version=\"0.7\"),\n    ])\n    using Plots, PlutoUI, LinearAlgebra\nend\nThis will 1) activate a temporary environment using Pkg.activate, 2) add the required packages, 3) import them with using. When running this in Pluto (try it out!), you will notice that the status marks next to packages disappear, and Pluto is running in ‘backwards compatibility mode’. Packages will no longer be installed or removed automatically, you have to use the Pkg REPL to do this yourself.Placing all code in a single begin block ensures that the lines will run in the correct order.Advanced: edit the notebook environmentPluto.jl includes a helper function Pluto.activate_notebook_environment that activates a notebook Pkg environment in the REPL:julia> import Pluto\n\njulia> Pluto.activate_notebook_environment(\"~/Documents/hello.jl\")\n\njulia> ]\n\n(hello.jl) > status\nAfter activating a notebook environment, you can use the Pkg REPL to view or modify the embedded environment. Changes from either side are synchronised (i.e. Pkg REPL changes are written to the notebook, editing the notebook updates the Pkg REPL env). Watch the demo video:"},{"url":"en/docs/packages/","title":"📦 Packages – Built-in package management","description":"Pluto.jl automatically manages a package environment for your notebook.","tags":["docs","reproducibility"],"text":"Pluto’s built-in package managementPluto has a built-in package manager, which means:🎈 Packages are automatically installed when you use import or using.🎈 Your package environment is stored inside the notebook file. When someone else opens your notebook with Pluto, the exact same package environment will be used, and packages will work on their computer.🙋 These two features are designed to make it easy to write and share reproducible notebooks.Basic usageInstalling and using packagesPluto will automatically install or remove packages while you work on your notebook. When you import a new package, Pluto will install it:🙋 Most packages will write installation instructions in their documentation: like “Run julia> ] install Example to install Example”.If you are using Pluto, you should skip these instructions, and import the package directly, using import Example or using Example.LogsInstalling packages can take some time, especially when starting Julia for the first time. Click on the status mark next to a package to view the installation progress. You can click on the  icon to view the logs.Removing packagesRemoving packages is automatic: when you delete code that imports a package, it will be uninstalled from the package environment. It is recommended to restart the notebook process afterwards to get a fresh start.Updating packagesYou can search for and install any available updates by clicking on the  icon. A backup of your notebook file will be created in the same folder as your notebook, in case the new versions do not work as expected.Long waiting timesJulia needs to download and precompile packages before you can use them. When using many packages, this can take a couple of minutes. Before installing a new package, Pluto can give an estimate of how long it will take to install:The estimates are available for popular packages, based on our own measurements.Pre-installed versions are preferredWhen adding a package to your notebook, Pluto will ask Pkg to install a version that was previously downloaded on your computer (with PRESERVE_ALL_INSTALLED). This was added in May 2024, on older versions, Pkg would always try to install the newest versions.This should make it much faster to open a notebook and import some packages that you already used recently. If you need the latest versions, then you have to use the Update button after adding the packages.Package installations are shared between environmentsIn Julia, packages are always installed globally, while environments (including notebooks) only store version information, not the package code itself. This means that multiple notebooks that use the same version of Plots will not lead to more disk usage or precompile time. (This is different from venv in Python/pip, or node_modules in NodeJS/npm, where every environment contains copies of package code by default.) Julia’s package manager is designed to work well with many package environments on the same computer.Of course, if different notebooks use different version of the same package, and you work on both in parallel, then source files for both versions will exist on your computer. A small price to pay for simpler reproducibility!In Julia 1.6, you can clean up package files that have not been used in a while with import Pkg; Pkg.gc(). In Julia 1.7 and up, this will be done automatically.Good to knowBased on PkgPluto’s package management is a wrapper around Pkg.jl (Julia’s built-in package manager) and RegistryInstances.jl. Packages are installed from the General registry.🙋 You can discover all available packages on juliahub.com.Isolated package environmentEvery notebook runs in its own isolated package environment. This ensures that your notebook code will not be influenced by packages installed elsewhere. (The LOAD_PATH is set to [\"@\", \"@stdlib\"].)Notebook filePluto stores the contents of Project.toml and Manifest.toml directly in the notebook file. For forwards-backwards compatibility, this is done using two extra “cells” at the bottom of the file, containing the two files as string literals. For example, here is a notebook that imports HypertextLiteral and PlutoUI: example file.🙋 Try it out! Open Pluto, import some packages and look at the notebook file!Fully reproducible environmentsWhen someone else opens your notebook for the first time, Pluto will install all required packages based on the information in the Manifest.toml file. This means that the exact same versions of all packages you used in the notebook will be installed, ensuring your work is fully reproducible when shared with others.Compatibility across Pluto versionsWhen opening an old Pluto notebook that does not have embedded project files, Pluto will generate them as if you typed those imports for the first time. If a call to Pkg.activate is made, the notebook will run in ‘backwards compatibility mode’, using the same environment and behaviour as old Pluto versions.Compatibility across Julia versionsThe Manifest.toml is designed to be (generally) backwards compatible: you can upgrade Julia and use an old manifest. However, the Manifest.toml is not always forwards compatible: a manifest generated generated with a newer version of Julia might not run on older versions.Pluto will always try to load the embedded manifest, and if it fails, it will discard the manifest (leaving only Project.toml) and try again. This is one reason why Pluto automatically adds [compat] ranges for each package in the Project.toml.Custom registriesPkg.jl supports additional private or public registries, which can be added in the Julia REPL with ] registry add https://github.com/myuser/MyRegistry.git, and this is also supported by Pluto’s package managemer.However, note that registries are not stored in the Project.toml/Manifest.toml files, which means that other people can only open your notebook if they added the custom registry before doing so. Alternatively, you can use a “Pkg cell” (more on this later) where you add the registry before adding packages.Learn more: advanced Pkg management"},{"url":"en/docs/plot/","title":"📊 Plotting","description":"How to plot data in Pluto, using Plots, Makie, Plotly and more.","tags":["docs","writing","plotting","plot","data","makie","plots","plotly","visualization"],"text":"Plotting in PlutoIt’s super easy to create plots in Pluto! There are many plotting libraries for Julia, and most will work well with Pluto.Plots.jlPlots.jl is an easy-to-use plotting library for Julia. It is a versatile plotting library, with a syntax that is similar to Python’s Matplotlib. To use it in Pluto, you add the following code to your notebook:using Plots\nplot([4,5,8,2,3,1,0])\nLarger code blocksYou often want to combine multiple plot calls in a single cell. The let block is really useful for this! Here is an example:data = rand(100)::Vector{Float64}\nlet\n    plot(data)\n\n    # use the ! explamation mark to modify the previous plot\n    scatter!(data)\n\n    # add a horizontal line\n\tmean = sum(data) / length(data)\n\thline!([mean]; label=\"Average value\")\nend\nUsing a let block instead of begin means that the variables defined in the block are local to the block, and they will not affect the rest of the notebook. In this example, the mean variable is only defined inside the let block, not in other cells.My plot is not showing!Sometimes, you create a plot in your code, but you don’t see it. This is because Pluto displays the last output of a cell . The plot function “creates a plot”, but it only gets displayed if the cell output is that object.For example, this code will not show a plot:let\n    x = 1:10\n    y = rand(10)\n    \n    plot(x, y, label=\"Data points\")\n    \n    for i in 1:length(x)\n        scatter!([x[i]], [y[i]], label=\"Point $i\")\n    end\nend\nThis is because the last expression in the let block is a for loop, which returns nothing. (So nothing will be displayed.)To fix it, add a plot!() call at the end of the cell. This will get the current plot, and just return it.let\n    x = 1:10\n    y = rand(10)\n    \n    plot(x, y, label=\"Data points\")\n    \n    for i in 1:length(x)\n        scatter!([x[i]], [y[i]], label=\"Point $i\")\n    end\n\n    # ✅ This is the fix!\n\tplot!()\nend\nTake a look at the Plots.jl featured notebook to learn more!Loading...Read featured notebook →\n\tconst notebook_html_url = \"https://featured.plutojl.org/plot/plots.jl\"\n\tconst white_svg_uri = \"data:image/svg+xml;utf8,<\\svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect width='100%' height='100%' fill='ivory'/><\\/svg>\"\n\n\tfetch(notebook_html_url).then(r => r.text()).catch(e => \"\").then(html_data => {\n\t\tconst doc = new DOMParser().parseFromString(html_data, \"text/html\");\n\t\tconst head = doc.head\n\n\t\tconsole.log({doc, notebook_html_url})\n\t\tconst q = sel => currentScript.parentElement.querySelector(\".pe-card\").querySelector(sel)\n\n\t\tq(\"a img\").src = head.querySelector('meta[property=\"og:image\"]')?.content ??\n\t\t\twhite_svg_uri\n\t\t\n\t\tq(\".pe-about h2\").innerText = (doc.title == \"\" ? null : doc.title) ?? \n\t\t\tnew URL(notebook_html_url).pathname.split(\"/\").map(decodeURIComponent).toReversed().find(s => s) ??\n\t\t\t\"Notebook\"\n\t\t\n\t\tq(\".pe-about p\").innerText = head.querySelector('meta[name=\"description\"]')?.content ?? \n\t\t\t\"\"\n\t})\n\n\n\t.pe-container {\n\t\tcontainer-type: inline-size;\n\t}\n\t\n\t.pe-card {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tmax-width: 700px;\n\n\t\tborder-radius: 6px;\n\t\tbackground: salmon;\n\t\tbackground: linear-gradient(80deg, #e9dbe3, #ffdabe);\n\t\tpadding: 10px;\n\t\tgap: 20px;\n\t\tmargin: 10px 0;\n\t\tbox-shadow: 0 2px 10px rgb(0 0 0 / 14%);\n\t}\n\n\t@container (max-width: 400px) {\n\t\t.pe-card {\n\t\t\tflex-direction: column;\n\t\t\tgap: 0;\n\t\t}\n\t\t.pe-about {\n\t\t\tmargin: 0 10px 10px 10px;\n\t\t}\n\t}\n\n\t.pe-card > a {\n\t\toverflow: hidden;\n\t\tborder-radius: 5px;\n\n\t\tflex: 0 0 35%;\n\t\taspect-ratio: 3 / 2;\n\t}\n\t\n\t.pe-card > a > img {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\t\n\t\tobject-fit: cover;\n\t}\n\n\tdiv.pe-about :is(p, h2) {\n\t\tcolor: black;\n\t\ttext-decoration: none;\n\t\tborder-bottom: none;\n\t\tmargin-block-end: 0;\n\t}\n\n\t.pe-right {\n\t\tflex: 1 1 auto;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: space-between;\n\t}\n\n\t.pe-nav {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.pe-nav a {\n\t\ttext-decoration: none;\n\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Cantarell, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n\t\"Segoe UI Symbol\", system-ui, sans-serif;\n\t\tfont-weight: 700;\n\t\tbackground: white;\n\t\tcolor: black;\n\t\tpadding: 8px 14px;\n\t\tborder-radius: 1000px;\n\t}\nMakie.jlMakie.jl is a powerful plotting library for Julia. It is built on top of the Julia plotting ecosystem and provides a simple interface for creating plots.Not all Makie backends work well with Pluto. The best option is to use the GLMakie or CairoMakie backend. To see an example, take a look at this featured notebook:Loading...GLMakie example →\n\tconst notebook_html_url = \"https://featured.plutojl.org/plot/heatmap.html\"\n\tconst white_svg_uri = \"data:image/svg+xml;utf8,<\\svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect width='100%' height='100%' fill='ivory'/><\\/svg>\"\n\n\tfetch(notebook_html_url).then(r => r.text()).catch(e => \"\").then(html_data => {\n\t\tconst doc = new DOMParser().parseFromString(html_data, \"text/html\");\n\t\tconst head = doc.head\n\n\t\tconsole.log({doc, notebook_html_url})\n\t\tconst q = sel => currentScript.parentElement.querySelector(\".pe-card\").querySelector(sel)\n\n\t\tq(\"a img\").src = head.querySelector('meta[property=\"og:image\"]')?.content ??\n\t\t\twhite_svg_uri\n\t\t\n\t\tq(\".pe-about h2\").innerText = (doc.title == \"\" ? null : doc.title) ?? \n\t\t\tnew URL(notebook_html_url).pathname.split(\"/\").map(decodeURIComponent).toReversed().find(s => s) ??\n\t\t\t\"Notebook\"\n\t\t\n\t\tq(\".pe-about p\").innerText = head.querySelector('meta[name=\"description\"]')?.content ?? \n\t\t\t\"\"\n\t})\n\n\n\t.pe-container {\n\t\tcontainer-type: inline-size;\n\t}\n\t\n\t.pe-card {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tmax-width: 700px;\n\n\t\tborder-radius: 6px;\n\t\tbackground: salmon;\n\t\tbackground: linear-gradient(80deg, #e9dbe3, #ffdabe);\n\t\tpadding: 10px;\n\t\tgap: 20px;\n\t\tmargin: 10px 0;\n\t\tbox-shadow: 0 2px 10px rgb(0 0 0 / 14%);\n\t}\n\n\t@container (max-width: 400px) {\n\t\t.pe-card {\n\t\t\tflex-direction: column;\n\t\t\tgap: 0;\n\t\t}\n\t\t.pe-about {\n\t\t\tmargin: 0 10px 10px 10px;\n\t\t}\n\t}\n\n\t.pe-card > a {\n\t\toverflow: hidden;\n\t\tborder-radius: 5px;\n\n\t\tflex: 0 0 35%;\n\t\taspect-ratio: 3 / 2;\n\t}\n\t\n\t.pe-card > a > img {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\t\n\t\tobject-fit: cover;\n\t}\n\n\tdiv.pe-about :is(p, h2) {\n\t\tcolor: black;\n\t\ttext-decoration: none;\n\t\tborder-bottom: none;\n\t\tmargin-block-end: 0;\n\t}\n\n\t.pe-right {\n\t\tflex: 1 1 auto;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: space-between;\n\t}\n\n\t.pe-nav {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.pe-nav a {\n\t\ttext-decoration: none;\n\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Cantarell, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n\t\"Segoe UI Symbol\", system-ui, sans-serif;\n\t\tfont-weight: 700;\n\t\tbackground: white;\n\t\tcolor: black;\n\t\tpadding: 8px 14px;\n\t\tborder-radius: 1000px;\n\t}\nLoading...CairoMakie example →\n\tconst notebook_html_url = \"https://featured.plutojl.org/math/convolution_1d.html\"\n\tconst white_svg_uri = \"data:image/svg+xml;utf8,<\\svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect width='100%' height='100%' fill='ivory'/><\\/svg>\"\n\n\tfetch(notebook_html_url).then(r => r.text()).catch(e => \"\").then(html_data => {\n\t\tconst doc = new DOMParser().parseFromString(html_data, \"text/html\");\n\t\tconst head = doc.head\n\n\t\tconsole.log({doc, notebook_html_url})\n\t\tconst q = sel => currentScript.parentElement.querySelector(\".pe-card\").querySelector(sel)\n\n\t\tq(\"a img\").src = head.querySelector('meta[property=\"og:image\"]')?.content ??\n\t\t\twhite_svg_uri\n\t\t\n\t\tq(\".pe-about h2\").innerText = (doc.title == \"\" ? null : doc.title) ?? \n\t\t\tnew URL(notebook_html_url).pathname.split(\"/\").map(decodeURIComponent).toReversed().find(s => s) ??\n\t\t\t\"Notebook\"\n\t\t\n\t\tq(\".pe-about p\").innerText = head.querySelector('meta[name=\"description\"]')?.content ?? \n\t\t\t\"\"\n\t})\n\n\n\t.pe-container {\n\t\tcontainer-type: inline-size;\n\t}\n\t\n\t.pe-card {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tmax-width: 700px;\n\n\t\tborder-radius: 6px;\n\t\tbackground: salmon;\n\t\tbackground: linear-gradient(80deg, #e9dbe3, #ffdabe);\n\t\tpadding: 10px;\n\t\tgap: 20px;\n\t\tmargin: 10px 0;\n\t\tbox-shadow: 0 2px 10px rgb(0 0 0 / 14%);\n\t}\n\n\t@container (max-width: 400px) {\n\t\t.pe-card {\n\t\t\tflex-direction: column;\n\t\t\tgap: 0;\n\t\t}\n\t\t.pe-about {\n\t\t\tmargin: 0 10px 10px 10px;\n\t\t}\n\t}\n\n\t.pe-card > a {\n\t\toverflow: hidden;\n\t\tborder-radius: 5px;\n\n\t\tflex: 0 0 35%;\n\t\taspect-ratio: 3 / 2;\n\t}\n\t\n\t.pe-card > a > img {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\t\n\t\tobject-fit: cover;\n\t}\n\n\tdiv.pe-about :is(p, h2) {\n\t\tcolor: black;\n\t\ttext-decoration: none;\n\t\tborder-bottom: none;\n\t\tmargin-block-end: 0;\n\t}\n\n\t.pe-right {\n\t\tflex: 1 1 auto;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tjustify-content: space-between;\n\t}\n\n\t.pe-nav {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tjustify-content: flex-end;\n\t}\n\n\t.pe-nav a {\n\t\ttext-decoration: none;\n\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Cantarell, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n\t\"Segoe UI Symbol\", system-ui, sans-serif;\n\t\tfont-weight: 700;\n\t\tbackground: white;\n\t\tcolor: black;\n\t\tpadding: 8px 14px;\n\t\tborder-radius: 1000px;\n\t}\nPlotlyYou can use the Plotly JS plotting library in Pluto! Check out the PlutoPlotly.jl package to get started.More librariesThere are more (experimental) plotting libraries for Julia. They probably work with Pluto, try them out!"},{"url":"en/docs/presentation/","title":"📈 Presentation mode","description":"How to use the Presentation Mode in Pluto.jl to present your Julia notebook as a slideshow.","tags":["docs","publishing","export","share","presentation","slideshow"],"text":"Presentation modePluto.jl has a built-in presentation mode that lets you view your notebook in full-screen as a slideshow. It’s very easy to use!How to start presentation modePresentation mode can be started from the Pluto.jl interface.Step 1Open your notebook in Pluto, and wait for all cells to finish running.Step 2Press the Share button in the top right.\nStep 3Click the “Slideshow” button.\nUsing presentation modeIn presentation mode, you can use the arrow buttons in the bottom right to move between slides. You can also use the keyboard arrow keys. Press the Escape key to exit presentation mode.If you want to present in full screen (without the browser addres bar, etc), use your browser’s full screen mode (F11).Slide separatorsPluto uses Markdown headers as slide separators: every time you write a header in Markdown, it is treated as a new slide. There are two slide types:#Header 1 creates a title slide: content will be centered vertically.##Header 2 creates a regular slide: the header appears on top of the screen, with content below.All other headers (### etc) do not create a new slide, they will be part of the previous slide.ExampleIf your notebooks contains these two cells:md\"\"\"\n# Here is a title slide!\nWith some extra content\n\"\"\"\nmd\"\"\"\n## This is a regular slide\nBlablabla\n\"\"\"\nIn regular Pluto, this looks like:Presentation modeIn presentation mode, this creates two slides:"},{"url":"en/docs/reactivity/","title":"🔄 Reactivity – how Pluto notebooks update automatically","description":"","tags":["docs","reproducibility"],"text":"Reactivity in Pluto.jlPluto notebooks are reactive! This means that when you change a value or a line of code, Pluto automatically updates all the cells that depend on it. No need to run cells one by one — Pluto figures out what needs to be updated, and does it for you. ✨In this example, changing the parameter A and running the first cell will directly re-evaluate the second cell and display the new plot.Why is reactivity important?Reproducibility: Your results always match your code. If you change an input, all outputs update instantly.No hidden state: You can’t accidentally use an old value—everything is always up to date.Easy exploration: Try out ideas quickly! Change a number, see what happens.How is this different from Jupyter?Cells run automatically when they need to. If a cell uses a variable, it will re-run when that variable changes.Global variables are deleted when their definition is removed. For example, if you change a cell from apple = 1 to banana = 2, then the apple variable will be deleted. It does not “linger around” in the background.You are not allowed to redefine a global variable in a second cell. Two cells cannot both define x.How does it work?Pluto tracks the dependencies between cells by looking at the syntax tree of your code. Pluto searches for variable assignments and references, and it uses this to build up a reactive dependency graph of your notebook.Using this dependency graph, Pluto knows how cells relate to each other. Pluto can search “up the tree” to find out which cells should run before, and “down the tree” to find out which cells depend on a given cell.Read more about Pluto’s reactivity algorithm in:ExpressionExplorer.jlPlutoDependencyExplorer.jlHelp I want to turn it off!Pluto does not have a global switch to turn off reactivity, there is no “Jupyter mode”. However, you can turn off reactivity for a specific cell! You can disable a cell.Learn how to disable cells"},{"url":"en/docs/search/","title":"Search results","description":"","tags":[],"text":"window.init_search();SearchResults\nLoading..."},{"url":"en/docs/status/","title":"🔋 Status","description":"The status tab in Pluto to see what's going on!","tags":["docs","editor","status"],"text":"Status tabThe status tab in Pluto shows you what is currently running. This includes cell execution, reactive code analysis, Pkg operations and starting the notebook process.Not visible on small screensIf your screen is not wide enough (like a phone screen), the Status tab is not visible. Try using your device in landscape mode, zooming out, or resizing the window.Notification 🔔You can ask Pluto to send you a notification when all items are done. (This button appears at the bottom of the status tab after a couple of seconds of activity.) This is useful if you are doing something that takes a long time to run, and you want to work on something else while you wait.Using this feature for the first time will prompt the browser to ask for permission to send you a notification.Current running cellTo jump to the cell that is currently running, you can either:Click on the task “Evaluating cells” → “Running code” in the Status tab.Click on the orange progress bar at the top of the screen."},{"url":"en/docs/threejs/","title":"Three.js in Pluto – example of using a JS library","description":"A simple example of using a JavaScript library in Pluto to create a visualisation library.","tags":["javascript","web","widgets","advanced","docs"],"text":"Fons wrote a short tutorial for using three.js in Pluto, as an example of using a JavaScript library in Pluto to create a simple visualisation library. Available at featured.plutojl.org/web/threejs!"},{"url":"en/docs/update/","title":"🌸 How to update","description":"","tags":["docs","introduction"],"text":"Update your Pluto installationYou can update Pluto using the Julia package manager. Open a Julia process and use Pkg to update Pluto:julia> import Pkg\njulia> Pkg.update(\"Pluto\")\nThis should update Pluto to the latest version (check our GitHub releases to find out!).Not the latest version?Sometimes, it is not possible to install the latest version of Pluto because of compatibility issues with other packages that you have installed in your environment.Some tips to fix it:First, use Pkg.status() to find out which packages you have installed, and remove any packages that you are no longer using. Now try to update again.If this did not work, try updating all packages (not just Pluto) with Pkg.update().Finally, you could use Pkg.status(outdated=true, mode=Pkg.PKGMODE_MANIFEST) to see the compatibility bounds. Here is an example.\nconst latest = fetch(\"https://api.github.com/repos/JuliaPluto/Pluto.jl/releases\", {\nmethod: \"GET\",\nmode: \"cors\",\ncache: \"no-cache\",\nheaders: {\n    \"Content-Type\": \"application/json\",\n},\nredirect: \"follow\",\nreferrerPolicy: \"no-referrer\",\n}).then(r => r.json()).then(r => r.reverse()).then(releases => releases[releases.length - 1].tag_name)\nlatest.then(v => {\nconst el = document.querySelector(\"#latesthere\")\nconsole.log(el, v)\nel.innerText = v\nel.style.fontWeight = \"bold\"\n})"}]