open-golang

A tiny Go library that opens files, directories, and URIs using the OS's default application, or a specific one you name.

Library
Go
vv0.0.0-20200116055534-eef842397966
812stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
35/100Needs Attention
Development Activity0
Maintenance0
Community52
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
58/100Fair
Architecture70
Code Quality45
Innovation30
Learning Curve85

open-golang gives Go programs a single cross-platform call to open a file, directory, or URI the way a user’s operating system would — the default app for that object type. It is a direct Go port of the popular node-open module, and internally shells out to open on macOS, start on Windows, and xdg-open on Linux, so callers don’t need to branch on runtime.GOOS themselves.

The API is deliberately minimal: Run and Start open with the OS default, while RunWith and StartWith let the caller specify an application by name (for example, forcing a URL open in Firefox). The Run/RunWith variants block until the external process exits and return its error, while Start/StartWith fire-and-forget. This makes the library a common building block in Go CLI tools that need to pop open a browser, a generated report, or a local file after finishing their main task.

What You Get

  • Run(input) - opens a file, directory, or URI in the OS default application and blocks until the external process exits, returning any error.
  • Start(input) - same as Run but does not wait for the external process to finish, useful for fire-and-forget launches.
  • RunWith(input, appName) - opens the target using a specifically named application (e.g. “firefox”) instead of the OS default, and waits for completion.
  • StartWith(input, appName) - opens the target with a named application without waiting for it to exit.

Common Use Cases

  • Launching a browser from a CLI tool - a command-line utility opens a generated report, dashboard URL, or OAuth login page in the user’s browser after finishing a task.
  • Opening generated files - a build or export tool opens the resulting PDF, HTML, or image file in whatever app the OS associates with that file type.
  • Revealing output directories - a tool opens the folder it just wrote output into, using the OS’s file manager.
  • Cross-platform tooling - developers building Go CLIs that must run identically on macOS, Windows, and Linux without hand-rolling exec.Command calls per platform.

Under The Hood

Architecture The package exposes four public functions in open.go (Run, Start, RunWith, StartWith) that all funnel into an unexported open()/openWith() pair, each implemented once per platform via Go build tags (exec_darwin.go for +build darwin, exec_windows.go for +build windows, and a catch-all exec.go for +build !windows,!darwin). Each platform file builds an *exec.Cmdopen/open -a <app> on macOS, rundll32 url.dll,FileProtocolHandler/cmd /C start on Windows, xdg-open/<appName> elsewhere — and the shared Run/Start wrappers simply call .Run() or .Start() on whichever *exec.Cmd the build-tagged function returned. Swapping the core abstraction (the platform command) means editing exactly one of the three per-OS files; the public API and calling code never change.

Tech Stack Pure standard library: os/exec for process invocation, path/filepath, os, and strings on Windows for constructing the rundll32 invocation and escaping & in URLs. No third-party dependencies, no build tooling beyond go build, and a Makefile that wraps go vet, golint, and go test. Distribution is via the module path github.com/skratchdot/open-golang, imported as open-golang/open.

Code Quality A single test file, open_test.go, covers all four exported functions but asserts on live, real-world side effects — it actually calls open.Run("https://google.com/") and expects no error, and separately expects an error for a bogus input string. This means the test suite requires a real desktop environment with a working browser/open handler to pass, and offers no isolation from the host machine’s state; there is no mocking of exec.Command. Naming is idiomatic Go (short, exported names matching stdlib conventions), and each per-platform file is small enough to audit at a glance. No linter config or CI workflow file is present in the clone beyond the Makefile’s go vet/golint targets.

What Makes It Unique The library’s value is entirely in triviality and platform coverage rather than novel technique: it is a faithful, minimal Go port of the Node.js node-open package, reduced to the smallest surface area needed to hide three OS-specific shell commands behind one call. There is no configuration, no extensibility hooks, and no dependency footprint — which is exactly why it has been vendored into many other Go CLI tools as a one-file-equivalent utility rather than treated as a heavyweight dependency.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search