# Runic.jl: A code formatter with rules set in stone

**URL:** <https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898>\
**Category:** Package Announcements\
**Created:** [August 6, 2024, 3:15pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898 "2024-08-06T15:15:46Z")\
**Posts on this page:** 12\
**Page:** 3

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [September 5, 2024, 2:13pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/41 "2024-09-05T14:13:29Z")

</div>

Right, they shouldn’t cause a problem in the end though because Runic doesn’t hit the deprecations in JuliaSyntax (which is the source of these errors). You can silence them by

```diff
diff --git a/contrib/juliac-buildscript.jl b/contrib/juliac-buildscript.jl
index 50f96198c4..1745b21ad4 100644
--- a/contrib/juliac-buildscript.jl
+++ b/contrib/juliac-buildscript.jl
@@ -123,6 +123,7 @@ end
     mapreduce_empty(::typeof(identity), op::F, T) where {F} = reduce_empty(op, T)
     mapreduce_empty(::typeof(abs), op::F, T) where {F} = abs(reduce_empty(op, T))
     mapreduce_empty(::typeof(abs2), op::F, T) where {F} = abs2(reduce_empty(op, T))
+ depwarn(msg, funcsym; force::Bool=false) = nothing
 end
 @eval Base.Unicode begin
     function utf8proc_map(str::Union{String,SubString{String}}, options::Integer, chartransform::F = identity) where F

```

(xref [add --trim option for generating smaller binaries by JeffBezanson · Pull Request #55047 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/55047#issuecomment-2277844004)) or change [Runic.jl/juliac/Makefile at 150ced92abc487b3ce47a0ce5d80aec501b6baab · fredrikekre/Runic.jl · GitHub](https://github.com/fredrikekre/Runic.jl/blob/150ced92abc487b3ce47a0ce5d80aec501b6baab/juliac/Makefile#L7) from `--unsafe-warn` to `--unsafe`.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 6, 2024, 5:09pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/42 "2024-11-06T17:09:20Z")

</div>

## Runic version 1.0.0

Runic is now registered in General. There have been some changes to the style, and a bunch of bugs have been found and fixed after using Runic “in the wild”. I think it should be very robust at this point. Some packages which now uses Runic include [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl), [Ferrite.jl](https://github.com/Ferrite-FEM/Ferrite.jl), and [Prometheus.jl](https://github.com/fredrikekre/Prometheus.jl).

Some things I want to mention:

- [`# runic: off` and `# runic: on`](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#toggle-formatting) “pragmas” for toggling formatting.
- [runic-action](https://github.com/marketplace/actions/runic-action) – a Github Action which simplifies the usage of Runic in CI.
- [runic-pre-commit](https://github.com/fredrikekre/runic-pre-commit) – a [pre-commit](https://pre-commit.com/) plugin to verify formatting when `git commit`ing.
- [A new section in the README](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#ignore-formatting-commits-in-git-blame) discussing how you can configure `git-blame` (locally and on GitHub) to ignore formatting commits.

Cheers!

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [November 6, 2024, 5:32pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/43 "2024-11-06T17:32:43Z")

</div>

Brilliant! Congratulations on such a comprehensive release 😀

I’m looking forward to adopting Runic (with a rules tweak or two) in my projects and wiring it up as an autoformatter for Julia code I write.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [December 18, 2024, 9:04am UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/44 "2024-12-18T09:04:55Z")

</div>

## Runic versions 1.1, 1.2, 1.3

Runic versions 1.1, 1.2, and 1.3 are released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md) for all changes.

Runic now support ranged formatting with the new `--lines=a:b` option which enables more surgical formatting of code. Based on this I want to highlight the new [Git integration](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#git-integration) provided by the [`git-runic`](https://github.com/fredrikekre/Runic.jl/blob/master/bin/git-runic) script. `git runic` applies formatting only to your _staged_ changes (but it can also be used to format the diff from multiple commits, see `git runic -h` for details). This enables incremental formatting of a code base as an alternative to going all in with Runic in a single large commit.

`git-runic` was contributed by @maleadt (thanks!) and is based on [`git-clang-format`](https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-format/git-clang-format) (git integration for [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html)). The following two blog posts give some more details about how `git-clang-format` (and thus `git-runic`) can be used:

- [Surgical formatting with git-clang-format](https://offlinemark.com/surgical-formatting-with-git-clang-format/)
- [Format your code - all the time](https://ortogonal.github.io/cpp/git-clang-format/)

Thanks!

---

<div class="post-metadata">

**Author:** ![chenpeizhi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenpeizhi/32/31620_2.png) [@chenpeizhi](https://discourse.julialang.org/u/chenpeizhi)\
**Post date:** [June 15, 2025, 2:23pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/46 "2025-06-15T14:23:46Z")

</div>

I think @Imshk has a point. Both Go and Python follow the style that @Imshk suggested. I agree that everything inside the function body should be indented, but the argument list is not part of the function body.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 14, 2026, 1:16pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/47 "2026-04-14T13:16:16Z")

</div>

## Runic versions 1.4, 1.5, 1.6

Runic versions 1.4, 1.5, and 1.6 are released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md) for all changes and fixes.

#### Installation as a Pkg App

Runic can now (since version 1.4) be installed as a [Pkg app](https://pkgdocs.julialang.org/dev/apps/) by running:

```julia
pkg> app add Runic

```

This is now the preferred installation method (see updated [installation](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#installation) and [editor integration](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#editor-integration) docs).

#### Updated JuliaSyntax version

Runic version 1.6 uses JuliaSyntax version 1 (instead of 0.4). This required quite large changes in Runic but shouldn’t mean that Runic format things differently (I have confirmed this on several large code bases which already user Runic).

#### Fixed “spec bugs”

Version 1.6.0 includes fixes for two [“specification bugs”](https://github.com/fredrikekre/Runic.jl/tree/master?tab=readme-ov-file#version-policy):

- Trailing comma in single line anonymous function argument lists are now removed. For example `(a, b,) -> a + b` will now be formatted correctly as `(a, b) -> a + b`.
- Runic enforces single space around keywords such as `function`, `while`, etc. However, `for` was previously not included in this formatting pass. Runic 1.6.0 will thus format e.g. `for i in I` as `for i in I`.

Both of these are rather unusual. In fact, across all the repos I tried Runic on, only one case of the former was detected.

Let me know here or on the issue tracker if something isn’t working correctly. Thanks!

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 22, 2026, 12:59pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/48 "2026-04-22T12:59:01Z")

</div>

## Runic version 1.7

Runic version 1.7 is released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md) for all changes and fixes. The headline feature in this release is that Runic can now format Julia code inside docstrings and inside Markdown files.

#### Formatting Julia code blocks in docstrings

A new opt-in flag `--docstrings` (and matching `docstrings::Bool` keyword argument to `Runic.format_file` / `Runic.format_string`) formats Julia code embedded in docstrings:

```sh
runic --docstrings --inplace src/

```

Fenced ````julia`, ````julia-repl`, and ````jldoctest` blocks have their contents run through Runic. In addition, all indented Markdown code blocks (including the leading method-signature block that many docstrings start with) are also formatted as Julia code. The `--docstrings` flag is also exposed through [`fredrikekre/runic-action`](https://github.com/fredrikekre/runic-action) and [`fredrikekre/runic-pre-commit`](https://github.com/fredrikekre/runic-pre-commit).

#### Formatting Markdown files

Embedded Julia code in Markdown files can now formatted by rewriting the embedded Julia code blocks (same rules as `--docstrings`). Dispatch is by file extension, so an explicit path just works:

```sh
runic --inplace README.md

```

For directory walks, a new `--extensions=<list>` flag controls which files are collected (default `jl`):

```sh
runic --extensions=jl,md --inplace .

```

Stdin input can also be routed through the Markdown formatter by passing a virtual filename:

```sh
cat README.md | runic --stdin-filename=stdin.md

```

The `--lines` option is supported with block-granular semantics: any code block whose line range overlaps a `--lines` range is formatted in full; blocks outside are left untouched. Markdown file formatting is also available through [`fredrikekre/runic-action`](https://github.com/fredrikekre/runic-action) and [`fredrikekre/runic-pre-commit`](https://github.com/fredrikekre/runic-pre-commit).

#### `git-runic` as a Pkg app

The [`git-runic`](https://github.com/fredrikekre/Runic.jl?tab=readme-ov-file#git-integration) Git integration (which applies Runic formatting incrementally by limiting it to lines added or modified in each commit) has been translated to Julia and is now shipped together with `runic` as part of the Pkg app. No more `curl`-ing a shell script:

```julia
pkg> app add Runic

```

This installs both `runic` and `git-runic` to `~/.julia/bin`. With that directory in `PATH`, `git runic` can be invoked directly from any git repository.

Let me know here or on the issue tracker if something isn’t working correctly. Thanks!

---

<div class="post-metadata">

**Author:** ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)\
**Post date:** [April 23, 2026, 7:13am UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/49 "2026-04-23T07:13:09Z")

</div>

`ALT + SHIFT + F` (on Windows) can only be tied to one formatter per file extension/format. For markdown files, is there an way to easily access both Markdown formatter and Runic? I imagine one of them will need to be manually called (`CTRL + SHIFT + P` then `format`, etc.) each time.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 23, 2026, 11:12am UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/50 "2026-04-23T11:12:40Z")

</div>

No idea, but sounds like a good opportunity to switch to Neovim.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [August 20, 2026, 8:27am UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/51 "2026-08-20T08:27:27Z")

</div>

## Runic version 1.8, 1.9

Runic versions 1.8 and 1.9 are released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md) for all changes and fixes.

To highlight a few things:

- Markdown formatting from version 1.7 is now also enabled for Quarto markdown files  
(`.qmd` extension).

- The CLI now have some extra guards when scanning input directories for Julia source  
files:

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [August 28, 2026, 5:05pm UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/52 "2026-08-28T17:05:28Z")

</div>

## Runic version 1.10

Runic versions 1.10 is released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md) for all changes.

Pretty minor release but it contains more complete line ending normalization that might simplify things for people using Git on Windows.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [October 2, 2026, 11:17am UTC](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898/53 "2026-10-02T11:17:03Z")

</div>

## Runic version 1.11, 1.12

Runic versions 1.11 and 1.12 are released, see [CHANGELOG](https://github.com/fredrikekre/Runic.jl/blob/master/CHANGELOG.md).

Version 1.11 only fixed a few rare corner cases but version 1.12 implements a new `--languages` option so that you can format also Documenters `@example`/`@setup`/`@repl` blocks in Markdown files (and docstrings).

[Previous page](https://discourse.julialang.org/t/runic-jl-a-code-formatter-with-rules-set-in-stone/117898.md?page=2)
