Download PDF

We are working to support a site-wide PDF but it is not yet available. You can download PDFs for individual lectures through the download badge on each lecture page.

How to read this lecture...

Code should execute sequentially if run in a Jupyter notebook

  • See the set up page to install Jupyter, Julia (1.0+) and all necessary libraries
  • Please direct feedback to or the discourse forum
  • For some notebooks, enable content with "Trust" on the command tab of Jupyter lab
  • If using QuantEcon lectures for the first time on a computer, execute ] add InstantiateFromURL inside of a notebook or the REPL

Julia Tools and Editors

Co-authored with Arnav Sood

While Jupyter notebooks are a great way to get started with the language, eventually you will want to use more powerful tools

We’ll discuss a few of them here, such as

  • Text editors like Atom, which come with rich Julia support for debugging, documentation, git integration, plotting and inspecting data, and code execution
  • The Julia REPL, which has specialized modes for package management, shell commands, and help
  • A virtualized Docker setup which provides a painless pre-configured environment on your machine

Note that we assume you’ve already completed the getting started and interacting with Julia lectures

Preliminary Setup

Follow the instructions for setting up Julia on your local computer

Creating a Startup File (Recommended)

Whenever the Julia compiler or REPL starts, it will look for a file called startup.jl (see Julia Manual)

We provide a file here which does two things

  • Makes the REPL shell mode “sticky,” so you don’t need to keep running ; for new commands
  • Loads the Revise.jl package on startup, which lets you see changes you make to a package in real-time (i.e., no need to quit the REPL, open again, and load again)

The location for the file is relative to your default Julia environment (e.g. ~/.julia/config/startup.jl or C:\Users\USERNAME\.julia\config\startup.jl on Windows)

Recall that you can find the location of the ~/.julia directory by running

In [1]:

Note: On Mac, this won’t be visible in the Finder unless you specifically enable that option, but you can get to it by running cd .julia; open . from a new terminal

To add the file:

  • In the julia terminal, type the following
] add  Revise REPL; precompile
  • Create the ~/.julia/config/ directory if necessary in the terminal or file explorer
  • Download the file startup.jl into that directory
  • For convenience, you may find it useful on your operating system to change the directory where the REPL starts

On Windows, if you have a shortcut on your desktop or on the taskbar, you could: (1) right-click on the icon; (2) right click on the “julia” text; (3) choose “Properties”, and (4) change the “Start In” to be something such as C:\Users\YOURUSERNAME\Documents


Previously, we discussed basic use of the Julia REPL (“Read-Evaluate-Print Loop”)

Here, we’ll consider some more advanced features

Shell Mode

Hitting ; brings you into shell mode, which lets you run bash commands (PowerShell on Windows)

In [2]:
; pwd

You can also use Julia variables from shell mode

In [3]:
x = 2
In [4]:
; echo $x

Package Mode

Hitting ] brings you into package mode

  • ] add Expectations will add a package (here, Expectations.jl)
  • Likewise, ] rm Expectations will remove that package
  • ] st will show you a snapshot of what you have installed
  • ] up will (intelligently) upgrade versions of your packages
  • ] precompile will precompile everytihng possible

You can get a full list of package mode commands by running

In [5]:
] ?
  Welcome to the Pkg REPL-mode. To return to the julia> prompt, either press
  backspace when the input line is empty or press Ctrl+C.


  pkg> cmd [opts] [args]

  Multiple commands can be given on the same line by interleaving a ; between
  the commands.


  activate: set the primary environment the package manager manipulates

  add: add packages to project

  build: run the build script for packages

  develop: clone the full package repo locally for development

  free: undoes a pin, develop, or stops tracking a repo

  gc: garbage collect packages not used for a significant time

  generate: generate files for a new project

  help: show this message

  instantiate: downloads all the dependencies for the project

  pin: pins the version of packages

  precompile: precompile all the project dependencies

  preview: previews a subsequent command without affecting the current state

  registry-add: add package registries

  registry-remove: remove package registries

  registry-status: information about installed registries

  registry-update: update package registries

  remove: remove packages from project or manifest

  resolve: resolves to update the manifest from changes in dependencies of
  developed packages

  status: summarize contents of and changes to environment

  test: run tests for packages

  update: update packages in manifest

On some operating systems (such as OSX) REPL pasting may not work for package mode, and you will need to access it in the standard way (i.e., hit ] first and then run your commands)

Help Mode

Hitting ? will bring you into help mode

The key use case is to find docstrings for functions and macros, e.g.

? print

Note that objects must be loaded for Julia to return their documentation, e.g.

? @test

will fail, but

using Test
? @test

will succeed


As discussed previously, eventually you will want to use a fully fledged text editor

The most feature-rich one for Julia development is Atom, with the Juno package

There are several reasons to use a text editor like Atom, including

  • Git integration (more on this in the next lecture)
  • Painless inspection of variables and data
  • Easily run code blocks, and drop in custom snippets of code
  • Integration with Julia documentation and plots

Installation and Configuration

Installing Atom

  1. Download and Install Atom from the Atom website
  2. (Optional, but recommended): Change default Atom settings

    • Use Ctrl-, to get the Settings pane
    • Choose the Packages tab
    • Type line-ending-selector into the Filter and then click “Settings” for that package

      • Change the default line ending to LF (only necessary on Windows)
    • Choose the Editor tab

      • Turn on Soft Wrap
      • Set the Tab Length default to 4

Installing Juno

  1. Use Ctrl-, to get the Settings pane
  2. Go to the Install tab
  3. Type uber-juno into the search box and then click Install on the package that appears
  4. Wait while Juno installs dependencies
  5. When it asks you whether or not to use the standard layout, click yes

At that point, you should see a built-in REPL at the bottom of the screen and be able to start using Julia and Atom


Sometimes, Juno will fail to find the Julia executable (say, if it’s installed somewhere nonstandard, or you have multiple)

To do this

  1. Ctrl-, to get Settings pane, and select the Packages tab
  2. Type in julia-client and choose Settings
  3. Find the Julia Path, and fill it in with the location of the Julia binary
  • To find the binary, you could run Sys.BINDIR in the REPL, then add in an additional /julia to the end of the screen
  • e.g. C:\Users\YOURUSERNAME\AppData\Local\Julia-1.0.1\bin\julia.exe on Windows as /Applications/ on OSX

See the setup instructions for Juno if you have further issues

Standard Layout

If you follow the instructions, you should see something like this when you open a new file

If you don’t, simply go to the command palette and type “Julia standard layout”

The bottom pane is a standard REPL, which supports the different modes above

The “workspace” pane is a snapshot of currently-defined objects

For example, if we define an object in the REPL

In [6]:
x = 2

Our workspace should read

The ans variable simply captures the result of the last computation

The Documentation pane simply lets us query Julia documentation

The Plots pane captures Julia plots output (the code is as follows)

using Plots
gr(fmt = :png);
data = rand(10, 10)
h = heatmap(data)

Note: The plots feature is not perfectly reliable across all plotting backends, see the Basic Usage page

Other Features

  • Shift + Enter will evaluate a highlighted selection or line (as above)
  • The run symbol in the left sidebar (or Ctrl+Shift+Enter) will run the whole file

See basic usage for an exploration of features, and the FAQ for more advanced steps (e.g. using with Docker)

Package Environments

Julia’s package manager lets you set up Python-style “virtualenvs,” or subsets of packages that draw from an underlying pool of assets on the machine

This way, you can work with (and specify) the dependencies (i.e., required packages) for one project without worrying about impacts on other projects

  • An environment is a set of packages specified by a Project.toml (and optionally, a Manifest.toml)
  • A registry is a git repository corresponding to a list of (typically) registered packages, from which Julia can pull (for more on git repositories, see version control)
  • A depot is a directory, like ~/.julia, which contains assets (compile caches, registries, package source directories, etc.)

Essentially, an environment is a dependency tree for a project, or a “frame of mind” for Julia’s package manager

  • We can see the default (v1.0) environment as such
In [7]:
] st
    Status `~/.julia/environments/v1.1/Project.toml`
  [63b64609] ExamplePackage v0.1.0 [`../../dev/ExamplePackage`]
  [7073ff75] IJulia v1.17.0
  [43edad99] InstantiateFromURL v0.2.1
  • We can also create and activate a new environment
In [8]:
] generate ExampleEnvironment
Generating project ExampleEnvironment:
  • And go to it
In [9]:
; cd ExampleEnvironment
  • To activate the directory, simply
In [10]:
] activate .

where “.” stands in for the “present working directory”

  • Let’s make some changes to this
In [11]:
] add Expectations Parameters
  Updating registry at `~/.julia/registries/General`
  Updating git-repo ``
 Resolving package versions...
  Updating `~/repos-collab/`
  [2fe49d83] + Expectations v1.0.2
  [d96e819e] + Parameters v0.10.3
  Updating `~/repos-collab/`
  [7d9fca2a] + Arpack v0.3.0
  [9e28174c] + BinDeps v0.8.10
  [b99e7846] + BinaryProvider v0.5.3
  [34da2185] + Compat v2.0.0
  [864edb3b] + DataStructures v0.15.0
  [31c24e10] + Distributions v0.16.4
  [2fe49d83] + Expectations v1.0.2
  [442a2c76] + FastGaussQuadrature v0.3.2
  [e1d29d7a] + Missings v0.4.0
  [bac558e1] + OrderedCollections v1.0.2
  [90014a1f] + PDMats v0.9.6
  [d96e819e] + Parameters v0.10.3
  [1fd47b50] + QuadGK v2.0.3
  [79098fc4] + Rmath v0.5.0
  [a2af1166] + SortingAlgorithms v0.3.1
  [276daf66] + SpecialFunctions v0.7.2
  [2913bbd2] + StatsBase v0.29.0
  [4c63d2b9] + StatsFuns v0.8.0
  [30578b45] + URIParser v0.4.0
  [2a0f44e3] + Base64 
  [ade2ca70] + Dates 
  [8bb1440f] + DelimitedFiles 
  [8ba89e20] + Distributed 
  [b77e0a4c] + InteractiveUtils 
  [76f85450] + LibGit2 
  [8f399da3] + Libdl 
  [37e2e46d] + LinearAlgebra 
  [56ddb016] + Logging 
  [d6f4376e] + Markdown 
  [a63ad114] + Mmap 
  [44cfe95a] + Pkg 
  [de0858da] + Printf 
  [3fa0cd96] + REPL 
  [9a3f8284] + Random 
  [ea8e919c] + SHA 
  [9e88b42a] + Serialization 
  [1a1011a3] + SharedArrays 
  [6462fe0b] + Sockets 
  [2f01184e] + SparseArrays 
  [10745b16] + Statistics 
  [4607b0f0] + SuiteSparse 
  [8dfed614] + Test 
  [cf7118a7] + UUIDs 
  [4ec0a83e] + Unicode 

Note the lack of commas

  • To see the changes, simply open the ExampleEnvironment directory in an editor like Atom

The Project TOML should look something like this

name = "ExampleEnvironment"
uuid = "14d3e79e-e2e5-11e8-28b9-19823016c34c"
authors = ["QuantEcon User <>"]
version = "0.1.0"

Expectations = "2fe49d83-0758-5602-8f54-1f90ad0d522b"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"

We can also

In [12]:
] precompile
Precompiling project...
Precompiling ExampleEnvironment
┌ Info: Precompiling ExampleEnvironment [75f0f89e-4504-11e9-0fb8-830f0da24d95]
└ @ Base loading.jl:1186

Note The TOML files are independent of the actual assets (which live in ~/.julia/packages, ~/.julia/dev, and ~/.julia/compiled)

You can think of the TOML as specifying demands for resources, which are supplied by the ~/.julia user depot

  • To return to the default Julia environment, simply
In [13]:
] activate

without any arguments

  • Lastly, let’s clean up
In [14]:
; cd ..
In [15]:
; rm -rf ExampleEnvironment


With this knowledge, we can explain the operation of the setup block

In [16]:
using InstantiateFromURL
activate_github("QuantEcon/QuantEconLecturePackages", tag = "v0.9.7");

What this activate_github function does is

  1. Download the TOML from that repo to a directory called .projects
  2. ] activate that environment, and
  3. ] instantiate and ] precompile, if necessary



Docker is a tool that lets you run preconfigured, lightweight environments as applications on your computer or in a computational cloud

The advantage of a Docker-based workflow is that it’s perfectly reproducible, and that setup (of Julia versions and dependencies, etc.) is handled upstream by the image maintainer

Here, we’ll walk through the setup and installation steps, along with the main features of the quantecon/base Docker image


  • First, create an account for Docker Hub and create a docker id
  • Next, download and install Docker for

    • Mac
    • Windows - do not choose to use Windows containers

Note: For Windows

  • Hyper-V support should be enabled. For Windows 10 users, this means you must use a Pro, Enterprise, or Education version (not Home or Mobile)
  • If you don’t meet these requirements, the Docker Toolbox for Windows may help
  • Next, to verify that there are no obvious errors in the installation, open a terminal (macOS/Linux) or Powershell (Windows) and run
docker pull hello-world
docker run hello-world

You should see something like

  • Then, download the QuantEcon Docker image by running the following in your terminal (this may take some time depending on your internet connection)
docker pull quantecon/base
  • Next, create a “data volume,” or a hidden directory where Docker will persist any changes to your Julia packages
docker volume rm quantecon
docker volume create quantecon

The first line will delete any existing volume we had with that name


The basic command is (Linux, OS/X)

docker run --rm -p 8888:8888 -v quantecon:/home/jovyan/.julia -v "$(pwd)":/home/jovyan/local quantecon/base

Or on Powershell on Windows

docker run --rm -p 8888:8888 -v quantecon:/home/jovyan/.julia -v ${PWD}:/home/jovyan/local quantecon/base
  • The rm instructs Docker to delete the container on exit,
  • The PWD statement will mount the local directory (i.e., where the terminal is) to the Docker for exchanging files
  • The p flag is for browser access
  • The quantecon:/home/jovyan/.julia mount is for persisting changes we make to the Julia user depot

You will see something like

In the output, you should see some text near that bottom that looks like

Copy the text after ?token= (e.g. 7c8f37bf32b1d7f0b633596204ee7361c1213926a6f0a44b)

In a browser, go to a URL like the following

To see something like


  • Ctrl+C is also the keyboard shortcut you use to kill the container, so be sure to copy using the mouse
  • When you call this command, Docker may require you to give it permissions to access the drive and the network. If you do not see the output within 20 or so seconds, then look for confirmation windows which may be hidden behind the terminal/etc.

Paste the text into Password or token: and choose Log in to get the full window

We can see that some packages are already pre-installed for our use

Maintenance and Troubleshooting

A few reminders

  • If you forget your token number, you may need to stop and restart the container
  • To stop the container, use Ctrl-C or type docker stop $(docker ps -aq) in a different terminal
  • To reset your Docker volume completely, redo the docker volume rm quantecon and docker volume create quantecon steps
  • To clean unnecessary Docker assets from your system, run docker system prune
  • If you can’t log in, make sure you don’t have an existing jupyter notebook occupying port 8888. To check, run jupyter notebook list and (if need be) jupyter notebook stop 8888. If you have difficulties, see this git issue