If you're writing anything more sophisticated than Blinky, steer clear of the Arduino IDE. It's great for beginners but lacks basic editor features making it painfully inefficient to use. Turn to Arduino's CLI tools instead and set them up for use with your favorite text editor.

Here's how.

Arduino >v1.5.0 ships with two command line tools: arduino and arduino-builder. We'll go over both tools in two parts, starting with arduino, the simpler of the two.

We'll start by going over intial set-up, do a deep-dive into the command line options, and finally test that everything works by uploading a sketch to our board. Let's jump right in!

Part 1: Using arduino

Normally, running arduino in the command line launches the Arduino IDE, but if you add any of the official command line options, a one-off compile or upload will place instead.


First things first, if you're working on macOS, the executable is Arduino.app/Contents/MacOS/Arduino and on Windows it is arduino_debug.exe.

On my Mac, I had some trouble trying to export the executable to my $PATH as well as symlinking to it. My workaround was to alias the arduino executable instead.

A Bash alias is nothing more than a keyboard shortcut and a way of avoiding typing a long command sequence.

To set up an alias for the Arduino executable, type:

alias arduino=/Applications/Arduino.app/Contents/MacOS/Arduino


Let's make sure this worked by typing arduino in the command line. If this launches the IDE, then you're all set.

Now, instead of having to type the entire path to the executable, you can save yourself the extra typing and simply type arduino to invoke the tool.

Compiling and Uploading

A full command takes the form:

arduino --board package:architecture:board[:parameters] --port /dev/deviceFileName --upload /file/path/to/file.ino 

Let's break this down so you know exactly what values each parameter expects.

Specifying Board

The board is specified via the --board flag. The argument passed to --board should be of the form package:architecture:board[:parameters], where:

  • For Arduino boards, let package=arduino.
  • For Avr-based boards -- including Arduino Uno, Mega, or Leonardo -- let architecture=avr.
  • For 32 bit SAM-based boards including the Arduino Due, let architecture=sam.
  • For the Arduino Uno, let board=uno, and for the Arduino Mega, let board=mega.

TIP: The value for any given board may be found in the boards.txt file in the architecture folder.

  • Parameters are often optional but can be used to specify a variant of a given board, such as the mega168 variant of the Arduino Nano board (in this case, let parameters equal cpu=atmega168).

In case board support for a given board is not installed on your computer, install using the command:

arduino --install-boards package "name:platform architecture[:version]"

Specifying Port

The port is specified with the --port flag. The argument passed to --port should be of the form /dev/deviceFileName, where deviceFileName is the name of the device being connected to.

To see a list of ports on MacOS, type:

% ls /dev/cu*

Verifying and Uploading

For this tutorial, we'll upload the familiar Blinky sketch as a quick way to make sure our setup works. Any sketch to be uploaded must be saved in a .ino file. Here is blinky.ino for reference:

void setup() {
  // initialize digital pin LED_BUILTIN as an output.

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000);  // wait for a second
  digitalWrite(LED_BUILTIN, LOW);  // turn the LED off by making the voltage LOW
  delay(1000);  // wait for a second

Now, verifying code is as simple as adding the --verify flag, whose argument should be the path to the .ino file.

Uploading is the same but with the --verify flag replaced by the --upload flag.

For an Arduino Uno, the command takes this form:

 arduino --board arduino:avr:uno --port /dev/cu.usbmodem1421 --upload blinky.ino

Ta-da! You're all set. 🎊

When you move on to writing more sophisticated code that relies on external libraries, make sure to enter

arduino --install-library "library_name[:version]"

with the library name and version (optionally) specified. This will ensure your libraries are installed before verification/upload.

Update: Further reading...

Part 2 of this series on arduino-builder set-up and usage is now up and can be found here. arduino-builder is used by the Arduino IDE under-the-hood and offers more advanced features.