CLI tool
JetBrains/go-modern-guidelines avatar
JetBrains/go-modern-guidelines

JetBrains/go-modern-guidelines: a Go version-aware skill for coding agents

Help AI coding agents write modern Go

3,512 stars114 forksGoApache-2.0

At a glance

What is it?
JetBrains ships a skill package that tells coding agents which Go idioms to prefer, keyed to the version in your go.mod. It is a documentation and prompt layer, not an analyzer, and its usefulness depends on how much you trust agent-side enforcement.
Who is it for?
Adopt this if your team already runs an agent inside a Go repository and wants the agent to reach for slices.Contains, cmp.Or or new(42) without being told each time. Skip it if your build pipeline is the only thing you trust to enforce style, since a skill file cannot fail a CI job.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The training-data lag that makes agents write Go 1.16 code

The README names two causes for stale agent output. The first is training data lag: a model cannot use errors.AsType[T] (described as a Go 1.26 addition) if it has never seen the function. The second is frequency bias, and this is the more interesting claim. Even when a model does know a newer form, the older form appears more often in the corpus it was trained on, so the older form wins. The README's own example is the counting loop: there is more for i := 0; i < n; i++ in the training data than for i := range n, so that is what comes out of the model.

That framing matters for who this is for. It is not aimed at Go developers learning the language. It is aimed at teams who have already put an agent in the loop on a Go codebase and are tired of reviewing diffs that rewrite idiomatic modern code back into pre-generics style. The repository is a JetBrains project under Apache-2.0, which is consistent with the fact that the install instructions are agent-specific rather than editor-specific: the deliverable is a skill that an agent loads, not a linter you point at a directory.

How the version detection and skill invocation actually work

The mechanism described in the README has three parts. First, the agent detects the project's Go version from go.mod. Second, it uses language features and standard library additions available up to and including that version. Third, it prefers modern idioms over older patterns. The guidelines themselves are said to cover Go 1.0 through Go 1.27 and to include everything targeted by the modernize analyzer, with FEATURES.md holding the full list plus examples.

The version gate is the part that separates this from a static style document. A single list of modern idioms would be wrong for anyone on an older toolchain, because suggesting cmp.Or in a module that declares an earlier Go version produces code that does not build. Reading go.mod first turns the guideline set into a filtered set. The README does not describe how the detection handles a missing go.mod, a workspace file, or a module that declares a version newer than the installed toolchain, so treat those as open questions rather than solved ones.

Invocation is automatic. For Junie, the README states the skill is invoked when it is relevant to a Go task. Claude Code behaves the same way, with an explicit escape hatch in the form of /modern-go-guidelines:use-modern-go. The other integrations are not described in terms of trigger logic at all, which suggests the automatic behavior is a property of the agent host rather than of the package.

Installing the skill: commands per agent host

The marketplace integrations install a small CLI on first use via go install, so the Go toolchain must be on PATH. That CLI lands in a local cache, given as ~/.cache/go-modern-guidelines or $XDG_CACHE_HOME/go-modern-guidelines, and the README states it never modifies your project. The target is Go 1.25 or newer; on an older Go it still works provided automatic toolchain switching is enabled, which is the GOTOOLCHAIN=auto default.

Junie CLI takes two commands inside a session: /extensions marketplace add JetBrains/go-modern-guidelines, then /extensions install modern-go-guidelines. Claude Code takes /plugin marketplace add JetBrains/go-modern-guidelines, then /plugin install modern-go-guidelines@goland-claude-marketplace. Codex runs in a terminal: codex plugin marketplace add JetBrains/go-modern-guidelines, then codex plugin add modern-go-guidelines@goland-codex-marketplace. Cursor adds the marketplace with cursor-agent plugin marketplace add https://github.com/JetBrains/go-modern-guidelines and then installs through the /plugins command inside a session. For anything else, npx skills add JetBrains/go-modern-guidelines installs the same skill, and --skill use-modern-go narrows it to this one.

Updating is where the hosts diverge, and the divergence is worth reading before you commit. Claude Code can auto-update the marketplace at startup, but the README notes automatic updates are disabled by default for third-party marketplaces, so you enable it once through /plugin, then Marketplaces, then goland-claude-marketplace. Codex has no in-place update: you upgrade the marketplace, remove the plugin, and add it again. Cursor refreshes the marketplace from Git but has no non-interactive command for updating an installed plugin, so the README tells you to reopen Cursor and reinstall via /plugins if the version is stale. Junie is the simplest case with /extensions update modern-go-guidelines.

Local development against the CLI, and what the dev flag changes

Contributors can point an agent at a local build. make dev-install builds the current checkout into the tool's cache, and setting GO_MODERN_GUIDELINES_DEV=1 in the agent's environment makes any agent using the plugin run that local build instead of the released version. The README states this works the same way across Claude Code, Codex and Cursor. The variable has to be exported before the agent launches so the agent process inherits it. After editing the CLI, run make dev-install again and the next call picks up the change. make dev-uninstall removes the build, and unsetting the variable returns the agent to the released version.

This is a better development story than editing a checked-in prompt file, because the same artifact is exercised across three hosts. It also means the CLI is the real unit of behavior. If you are evaluating the project and want to know whether a given Go feature is covered, the honest path is to read FEATURES.md rather than to infer coverage from the README's examples, which name max(a, b), slices.Contains, cmp.Or(a, b, c), new(42) and errors.AsType[T](err) and nothing more.

What this cannot do: no enforcement, no diagnostics

Nothing in the README describes a check that fails. The guidelines are text an agent reads before writing code. If the agent ignores them, or if a developer writes the old pattern by hand, or if a reviewer approves it, nothing in this repository objects. Compare that with the modernize analyzer, which the README itself cites as the Go team's tool for updating existing code to newer idioms. The relationship is stated plainly: modernize fixes code that already exists, these guidelines aim to prevent the outdated code from being written in the first place. Those are complementary positions, and only one of them produces a nonzero exit code.

The second limitation is scope of the target. The README says the guidelines cover features from Go 1.0 through Go 1.27, but the CLI targets Go 1.25 or newer. The stated fallback for older toolchains depends on GOTOOLCHAIN=auto being enabled, which lets Go fetch a compatible toolchain on first run. In an environment with GOTOOLCHAIN=local, or with no network access to the module proxy on first use, the install step has a problem the README does not address. That is a real constraint for air-gapped or strictly pinned build environments, and it is the first thing to test before a wider rollout.

The third limitation is that the README does not specify how conflicts are resolved. If a repository has its own style guide that disagrees with a guideline in FEATURES.md, the material gives no precedence rule.

Alternatives: the modernize analyzer and a checked-in style guide

The most direct alternative is the modernize analyzer, and the difference in approach is not cosmetic. modernize is a program you run over source; it reports or rewrites code that does not match current idioms, and its output is machine-checkable. These guidelines are input to a generative process, so their effect is probabilistic and their failures are silent. If your goal is to stop outdated patterns from reaching main, an analyzer in CI does that. If your goal is to stop an agent from producing them in the first place, this repository addresses a step earlier in the pipeline. Running both is coherent, but only if you understand that the analyzer is the one making a guarantee.

The second alternative is the thing most teams already have: a CONTRIBUTING.md or an internal style document checked into the repository. The practical difference is delivery. A checked-in document is read by humans and, at best, pasted into an agent's context by hand. This project packages the same kind of content as an agent skill with an install path per host and a version gate driven by go.mod. The repository does include a CONTRIBUTING.md of its own, referenced in the README for people proposing changes to the guidelines, which is a reminder that the content itself is maintained by hand and will drift from the Go release schedule unless someone keeps it current.

Licence, maintenance and the cost of keeping the list current

The repository is Apache-2.0, which permits commercial use and modification and includes an explicit patent grant. That matters here because the artifact is content you may want to fork and trim to your own house style. If you do fork, the update commands in the README stop applying to you: Claude Code's auto-update path, the Codex remove-and-add sequence and the Cursor /plugins reinstall all assume you are pulling from the JetBrains marketplace entries named in the install commands. A fork means you own the refresh path. This is a description of the licence terms, not legal advice, and the usual caveat applies: read the LICENSE file and the NOTICE handling yourself if you redistribute.

Maintenance cost has two components. The upstream side is the guideline content, which has to track Go releases; the README's own framing, covering Go 1.0 through 1.27, sets an expectation of continuous editing. The downstream side is the host integration. Cursor having no non-interactive plugin update command means a Cursor user's refresh is a manual, interactive step, and Codex's three-command sequence is easy to script but easy to forget. Neither is a reason to avoid the project, but both are recurring work that a team should assign rather than assume.

Editorial conclusion

Adopt this if your team already runs an agent inside a Go repository and wants the agent to reach for slices.Contains, cmp.Or or new(42) without being told each time. Skip it if your build pipeline is the only thing you trust to enforce style, since a skill file cannot fail a CI job. Before rolling it out, open FEATURES.md and check which of the listed features your pinned Go version actually supports, then confirm the agent is reading go.mod rather than assuming a version.

Official sources

  1. Issues
  2. JetBrains/go-modern-guidelines on GitHub
  3. License: Apache-2.0
  4. README
Community notes

Community notes