# `Biomine`
[🔗](https://github.com/wingyplus/biomine/blob/main/lib/biomine.ex#L1)

Elixir bindings for the [Biome](https://biomejs.dev/) formatter, exposed as a
Rust NIF. Format JavaScript/TypeScript and CSS source directly from Elixir
without shelling out to Node.

    iex> Biomine.format_js("const  x=1")
    {:ok, "const x = 1;\n"}

The NIF ships as a precompiled binary via
[`rustler_precompiled`](https://hexdocs.pm/rustler_precompiled), so no Rust
toolchain is required to use this library — the matching artifact for your
OS, architecture, and NIF version is downloaded automatically at compile
time.

## Mix formatter plugins

Biomine can be used as a `mix format` plugin for JavaScript/TypeScript and
CSS files via `Biomine.Mix.JsFormatter` and `Biomine.Mix.CssFormatter`, and
as a `Phoenix.LiveView.HTMLFormatter.TagFormatter` via
`Biomine.LiveView.TagFormatter` for formatting `<script>` and `<style>` tags
(including colocated hooks and colocated CSS) in `.heex` templates. See
those modules, or the [README](https://github.com/wingyplus/biomine), for
setup instructions.

# `format_css`

Format CSS source.

Returns `{:ok, formatted_source}` when formatting succeeds.

Returns `{:error, {:parse_error, diagnostics}}` when the source cannot be
parsed and `{:error, :invalid_option}` when an unsupported option or option
value is provided.

## Options

* `:indent_style` - Indentation style, either `:tab` or `:space`. The default value is `:space`.

* `:indent_width` (`t:non_neg_integer/0`) - Indentation width as an integer. The default value is `2`.

* `:line_ending` - Line ending style, one of `:lf`, `:crlf`, or `:cr`. The default value is `:lf`.

* `:line_width` - Maximum line width as an integer from 1 to 320. The default value is `120`.

* `:quote_style` - CSS quote style, either `:double` or `:single`.

* `:tailwind_directives` (`t:boolean/0`) - Enables parsing of Tailwind CSS 4.0 directives and functions, like `@theme`, `@utility`, and `@apply`. The default value is `false`.

## Examples

    iex> Biomine.format_css("a{color:red}")
    {:ok, "a {\n  color: red;\n}\n"}

    iex> Biomine.format_css(~s(a{content:"hi"}), quote_style: :single)
    {:ok, "a {\n  content: 'hi';\n}\n"}

    iex> Biomine.format_css("a {")
    {:error,
     {:parse_error,
      [
        %{
          message: "expected `}` but instead the file ends",
          span: %{start: 3, end: 3}
        }
      ]}}

# `format_js`

Format JavaScript/TypeScript source.

Returns `{:ok, formatted_source}` when formatting succeeds.

Returns `{:error, {:parse_error, diagnostics}}` when the source cannot be
parsed and `{:error, :invalid_option}` when an unsupported option or option
value is provided.

## Options

* `:indent_style` - Indentation style, either `:tab` or `:space`. The default value is `:space`.

* `:indent_width` (`t:non_neg_integer/0`) - Indentation width as an integer. The default value is `2`.

* `:line_ending` - Line ending style, one of `:lf`, `:crlf`, or `:cr`. The default value is `:lf`.

* `:line_width` - Maximum line width as an integer from 1 to 320. The default value is `120`.

* `:quote_style` - JavaScript quote style, either `:double` or `:single`.

* `:jsx_quote_style` - JSX quote style, either `:double` or `:single`.

* `:quote_properties` - Object property quote handling, either `:as_needed` or `:preserve`.

* `:trailing_comma` - Trailing comma style, one of `:all`, `:es5`, or `:none`.

* `:semicolons` - Semicolon style, either `:always` or `:as_needed`.

* `:arrow_parentheses` - Arrow function parentheses style, either `:always` or `:as_needed`.

* `:bracket_spacing` (`t:boolean/0`) - Whether to print spaces inside object literal brackets.

* `:bracket_same_line` (`t:boolean/0`) - Whether to keep closing JSX brackets on the same line.

* `:attribute_position` - JSX attribute position style, either `:auto` or `:multiline`.

## Examples

    iex> Biomine.format_js("let x=1")
    {:ok, "let x = 1;\n"}

    iex> Biomine.format_js("let x='hello'", quote_style: :single)
    {:ok, "let x = 'hello';\n"}

    iex> Biomine.format_js("funtion f(")
    {:error,
     {:parse_error,
      [
        %{
          message: "Expected a semicolon or an implicit semicolon after a statement, but found none",
          span: %{start: 8, end: 9}
        },
        %{
          message: "expected `)` but instead the file ends",
          span: %{start: 10, end: 10}
        }
      ]}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
