Zurück zum Ranking

air-verse/air

Go

☁️ Live reload for Go apps

toolsgolive-reloadginwatchertask-runnerdockerfile-watcher
Sterne-Wachstum
Sterne
23.8k
Forks
920
Wochenwachstum
Issues
2
10k20k
Okt. 2017Sept. 2020Aug. 2023Juli 2026
ArtefakteGo Modulesgo get github.com/air-verse/air
README

:cloud: Air - Live reload for Go apps

Go Codacy Badge codecov

air

English | 简体中文 | 繁體中文 | 日本語

Motivation

When I started developing websites in Go and using gin framework, it was a pity that gin lacked a live-reloading function. So I searched around and tried fresh, it seems not much flexible, so I intended to rewrite it better. Finally, Air's born. In addition, great thanks to pilu, no fresh, no air :)

Air is yet another live-reloading command line utility for developing Go applications. Run air in your project root directory, leave it alone, and focus on your code.

Note: This tool has nothing to do with hot-deploy for production.

Features

  • Colorful log output
  • Customize build or any command
  • Support excluding subdirectories
  • Allow watching new directories after Air started
  • Better building process
  • Configurable .env file loading

Overwrite specify configuration from arguments

Support air config fields as arguments:

You can view the available command-line arguments by running the following commands:

air -h

or

air --help

If you want to config build command and run command, you can use like the following command without the config file:

air --build.cmd "go build -o bin/api cmd/run.go" --build.entrypoint "./bin/api"

Use a comma to separate items for arguments that take a list as input:

air --build.cmd "go build -o bin/api cmd/run.go" --build.entrypoint "./bin/api" --build.exclude_dir "templates,build"

List arguments can also be repeated, and the values are appended in the order they appear. This is handy when the command line is generated by a script or Makefile:

# equivalent to --env_files ".env,.env.local,.env.secret"
air --env_files ".env,.env.local" --env_files ".env.secret"

Installation

With go 1.25 or higher:

go install github.com/air-verse/air@latest

Via go get -tool (project install)

With go 1.25 or higher:

go get -tool github.com/air-verse/air@latest

# then use it like so:
go tool air -v

Via install.sh

# binary will be $(go env GOPATH)/bin/air
curl -sSfL https://raw.githubusercontent.com/air-verse/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

# or install it into ./bin/
curl -sSfL https://raw.githubusercontent.com/air-verse/air/master/install.sh | sh -s

air -v

Via goblin.run

# binary will be /usr/local/bin/air
curl -sSfL https://goblin.run/github.com/air-verse/air | sh

# to put to a custom path
curl -sSfL https://goblin.run/github.com/air-verse/air | PREFIX=/tmp sh

Via Homebrew

brew install go-air

Via Scoop

scoop install air

Using software package manager mise

mise use -g air

Docker/Podman

Please pull this Docker image cosmtrek/air.

docker/podman run -it --rm \
    -w "<PROJECT>" \
    -e "air_wd=<PROJECT>" \
    -v $(pwd):<PROJECT> \
    -p <PORT>:<APP SERVER PORT> \
    cosmtrek/air
    -c <CONF>

Docker/Podman .${SHELL}rc

if you want to use air continuously like a normal app, you can create a function in your ${SHELL}rc (Bash, Zsh, etc…)

air() {
  podman/docker run -it --rm \
    -w "$PWD" -v "$PWD":"$PWD" \
    -p "$AIR_PORT":"$AIR_PORT" \
    docker.io/cosmtrek/air "$@"
}

<PROJECT> is your project path in container, eg: /go/example if you want to enter the container, Please add --entrypoint=bash.

For example

One of my project runs in Docker:

docker run -it --rm \
  -w "/go/src/github.com/cosmtrek/hub" \
  -v $(pwd):/go/src/github.com/cosmtrek/hub \
  -p 9090:9090 \
  cosmtrek/air

Another example:

cd /go/src/github.com/cosmtrek/hub
AIR_PORT=8080 air -c "config.toml"

this will replace $PWD with the current directory, $AIR_PORT is the port where to publish and $@ is to accept arguments of the application itself for example -c

Usage

If you installed Air with go install, make sure your Go bin directory is in your PATH:

export PATH="$PATH:$(go env GOPATH)/bin"

First enter into your project

cd /path/to/your_project

The simplest usage is to run

# first tries `.air.toml` in current directory; if not found, uses defaults
air

To use a specific config file explicitly, pass -c:

air -c .air.toml

You can initialize the .air.toml configuration file to the current directory with the default settings running the following command.

air init

After this, you can just run the air command without additional arguments, and it will use the .air.toml file for configuration.

air

For modifying the configuration refer to the air_example.toml file.

Runtime arguments

You can pass arguments for running the built binary by adding them after the air command.

# Will run ./tmp/main bench
air bench

# Will run ./tmp/main server --port 8080
air server --port 8080

You can separate the arguments passed for the air command and the built binary with -- argument.

# Will run ./tmp/main -h
air -- -h

# Will run air with custom config and pass -h argument to the built binary
air -c .air.toml -- -h

Startup banner

Use misc.startup_banner to control what Air prints at startup.

[misc]
# Not set (default): show built-in ASCII banner with version.

# Set to empty string: print nothing.
startup_banner = ""

# Set to custom text: print this text instead of the built-in banner.
# startup_banner = "API watcher"

Entrypoint

Use build.entrypoint to point at the binary generated by build.cmd and describe how it should be executed. The value can be either a string (just the executable) or an array of strings. When using an array, the first element is the executable (resolved relative to root unless it lacks a path separator, in which case $PATH is consulted) and every subsequent element is treated as a default argument. Values from build.args_bin and the command line are appended after the inline arguments. The legacy build.bin field is deprecated and will be removed in a future release, so prefer the entrypoint form going forward.

[build]
entrypoint = ["./tmp/main"]
args_bin = ["server", ":8080"]

# Inline the default arguments directly after the binary.
entrypoint = ["./tmp/main", "server", ":8080"]

# Use PATH-resolved tools like dlv by omitting path separators.
entrypoint = [
  "dlv", "exec", "--accept-multiclient", "--log", "--headless", "--continue",
  "--listen=:8999", "--api-version", "2", "./tmp/main",
]

Environment Files

Air can automatically load environment variables from .env files before both building and running when env_files is configured.

# Loads .env.development and then .env files.
# Values in the lattermost file overwrite any preceding ones.
# Does not overwrite variables that were present before running air.
env_files = [".env.development", ".env"]

Platform-specific build overrides

You can override build settings per OS with [build.windows], [build.darwin], and [build.linux]. These blocks override the base [build] values when running on the matching platform. Only the fields below are supported in platform blocks: pre_cmd, cmd, post_cmd, bin, entrypoint, full_bin, args_bin.

[build]
cmd = "go build -o ./tmp/main ."
bin = "./tmp/main"

[build.windows]
cmd = "go build -o ./tmp/main.exe ."
bin = "tmp\\main.exe"
entrypoint = ["tmp\\main.exe"]

Running air init adds a platform block for the current OS when its defaults differ from the base configuration.

Watch rules: run a command instead of rebuilding

Sometimes a change should run a command rather than rebuild your app — frontend assets served from disk, templ/sqlc/go generate pipelines, and so on. Declare a [[build.rules]] block for each of them:

[build]
cmd = "go build -o ./tmp/main ."
# the main build ignores the frontend...
exclude_dir = ["web"]

# ...but this rule watches it and rebuilds the assets on change
[[build.rules]]
name = "assets"
include_dir = ["web"]
include_ext = ["js", "ts", "css"]
cmd = "npm run build"

[[build.rules]]
name = "templ"
include_ext = ["templ"]
cmd = "templ generate"

A file matched by a rule runs the rule's cmd and never triggers a rebuild, even if it would also match the main build's watch settings. Rule directories are watched even when listed in exclude_dir. If a rule's command generates files the main build watches (for example, templ generate writing .go files), the rebuild follows naturally.

Each rule supports include_dir, include_ext, include_file, exclude_regex, and a delay (debounce in milliseconds, default 1000). At least one of the include_* matchers is required. Rules run their commands to completion; changes arriving meanwhile queue a follow-up run.

Docker Compose

services:
  my-project-with-air:
    image: cosmtrek/air
    # working_dir value has to be the same of mapped volume
    working_dir: /project-package
    ports:
      - <any>:<any>
    environment:
      - ENV_A=${ENV_A}
      - ENV_B=${ENV_B}
      - ENV_C=${ENV_C}
    volumes:
      - ./project-relative-path/:/project-package/

Debug

air -d prints all logs.

Installation and Usage for Docker users who don't want to use air image

Dockerfile

# Choose whatever you want, version >= 1.25
FROM golang:1.25-alpine

WORKDIR /app

RUN go install github.com/air-verse/air@latest

COPY go.mod go.sum ./
RUN go mod download

CMD ["air", "-c", ".air.toml"]

docker-compose.yaml

version: "3.8"
services:
  web:
    build:
      context: .
      # Correct the path to your Dockerfile
      dockerfile: Dockerfile
    ports:
      - 8080:3000
    # Important to bind/mount your codebase dir to /app dir for live reload
    volumes:
      - ./:/app

Q&A

"command not found: air" or "No such file or directory"

export GOPATH=$HOME/xxxxx
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
export PATH=$PATH:$(go env GOPATH)/bin #Confirm this line in your .profile and make sure to source the .profile if you add it!!!

Error under wsl when ' is included in the bin

Should use \ to escape the ' in the bin. related issue: #305

Question: how to do hot compile only and do not run anything?

#365

[build]
  cmd = "/usr/bin/true"

How to Reload the Browser Automatically on Static File Changes

Refer to issue #512 for additional details.

  • Ensure your static files in include_dir, include_ext, or include_file.
  • Ensure your HTML has a </body> tag
  • Activate the proxy by configuring the following config:
[proxy]
  enabled = true
  proxy_port = <air proxy port>
  app_port = <your server port>

Development

Please note that it requires Go 1.25+ (see go.mod).

# Fork this project

# Clone it
mkdir -p $GOPATH/src/github.com/cosmtrek
cd $GOPATH/src/github.com/cosmtrek
git clone git@github.com:<YOUR USERNAME>/air.git

# Install dependencies
cd air
make ci

# Explore it and happy hacking!
make install

Pull requests are welcome.

Release

# Checkout to master
git checkout master

# Add the version that needs to be released
git tag v1.xx.x

# Push to remote
git push origin v1.xx.x

# The CI will process and release a new version. Wait about 5 min, and you can fetch the latest version

Star History

Star History Chart

Buy Me A Coffee

Give huge thanks to lots of supporters. I've always been remembering your kindness.

License

GNU General Public License v3.0

Ähnliche Repositories
sherlock-project/sherlock

Hunt down social media accounts by username across social networks

PythonPyPIMIT Licenseosintreconnaissance
sherlockproject.xyz
86.9k10.2k
hoppscotch/hoppscotch

Open-Source API Development Ecosystem • https://hoppscotch.io • Offline, On-Prem & Cloud • Web, Desktop & CLI • Open-Source Alternative to Postman, Insomnia

TypeScriptnpmMIT Licenseapiapi-client
hoppscotch.io
79.8k6k
ocornut/imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

C++MIT Licenseguigamedev
74.9k11.9k
elder-plinius/CL4R1T4S

LEAKED SYSTEM PROMPTS FOR CHATGPT, CLAUDE, GEMINI, GROK, PERPLEXITY, CURSOR, LOVABLE, REPLIT, AND MORE! - AI SYSTEMS TRANSPARENCY FOR ALL! 👐

GNU Affero General Public License v3.0aichatgpt
45.9k9.3k
CorentinTh/it-tools

Collection of handy online tools for developers, with great UX.

VueGNU General Public License v3.0vuejstools
it-tools.tech
39.9k5.2k
veggiemonk/awesome-docker

:whale: A curated list of Docker resources and projects

Apache License 2.0dockerawesome
average.joe.dev/awesome-docker/
36.5k3.3k
jaywcjlove/linux-command

Linux命令大全搜索工具,内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux

MarkdownMIT Licenselinuxlinux-command
jaywcjlove.github.io/linux-command
36.5k6.6k
ibraheemdev/modern-unix

A collection of modern/faster/saner alternatives to common unix commands.

listsunix
33k830
luong-komorebi/Awesome-Linux-Software

🐧 A list of awesome Linux softwares

HTMLlinux-desktopdesktop-environment
luong-komorebi.github.io/Awesome-Linux-Software/
25.5k2.2k
HumanSignal/labelImg

LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out Label Studio, the open source data labeling tool for images, text, hypertext, audio, video and time-series data.

PythonPyPIMIT Licensepython2python3
youtu.be/p0nR2YsCY_U
25.1k6.6k
eza-community/eza

A modern alternative to ls

Rustcrates.ioEuropean Union Public License 1.2colorcommand-line
eza.rocks
22.7k478
Zeyi-Lin/HivisionIDPhotos

⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。

PythonPyPIApache License 2.0demogradio
modelscope.cn/studios/SwanLab/HivisionIDPhotos
21.3k2.4k