# format

A command to reformat a SurrealQL file to a consistent style, printing the result or writing it back in place.

_(since v3.3.0)_

Reformat a SurrealQL file, or a query read from standard input, without connecting to a server. The command parses each statement and prints it back out from the parsed syntax tree, so the result reflects what the statements are rather than how they were typed.

> [!NOTE]
> **Before you start** - make sure you've [installed SurrealDB](/docs/running/installation.md).

<Synopsis>
surreal format [OPTIONS] <FILE>
</Synopsis>

`fmt` is an alias for `format`, so `surreal fmt query.surql` runs the same command.

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<FILE>",
            "required": true,
            "description": "Path to the SurrealQL file to format. Use `-` to read from standard input."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--write",
            "short": "-w",
            "description": "Overwrite the file with the formatted output instead of printing it to standard output."
        },
        {
            "name": "--log",
            "short": "-l",
            "value": "<LOG>",
            "default": "info",
            "env": "SURREAL_LOG",
            "description": "The logging level for the command-line tool. Possible values: `none`, `full`, `error`, `warn`, `info`, `debug`, `trace`."
        }
    ]}
/>

## Example usage

Take a file written in lowercase, with double-quoted strings and a run of blank lines in the middle:

```surql title="person.surql"
-- Set up the person table
define table person schemafull;
define field name on person type string;
define field age on person type int;


create person:tobie set name="Tobie", age=35;
select name, age from person where age>18 order by name;
```

Passing the path to `surreal format` prints the formatted file to standard output and leaves the file on disk untouched.

```bash
surreal format person.surql
```

```surql title="Output"
-- Set up the person table
DEFINE TABLE person TYPE NORMAL SCHEMAFULL
	PERMISSIONS NONE;
DEFINE FIELD name ON person TYPE string
PERMISSIONS FULL;
DEFINE FIELD age ON person TYPE int
PERMISSIONS FULL;

CREATE person:tobie SET name = 'Tobie', age = 35;
SELECT name, age FROM person WHERE age > 18 ORDER BY name;
```

Each statement comes back with its keywords in uppercase, single-quoted strings, spaces around operators, and the clauses that were left implicit written out in full. `DEFINE TABLE person SCHEMAFULL` becomes `DEFINE TABLE person TYPE NORMAL SCHEMAFULL PERMISSIONS NONE`, which is the same definition the server stores and the same one [`INFO FOR DB`](/docs/reference/query-language/statements/info.md) reports.

## Writing the result back to the file

The `--write` flag replaces the contents of the file with the formatted output and prints nothing.

```bash
surreal format --write person.surql
```

Running the command a second time on an already formatted file leaves it unchanged, so `--write` is safe to run repeatedly.

## Formatting input from stdin

Pass `-` as the file to read the query from standard input and write the result to standard output.

**Bash**

```bash
echo 'select * from person where age>18 order by name desc limit 5;' | surreal format -
```

```surql title="Output"
SELECT * FROM person WHERE age > 18 ORDER BY name DESC LIMIT 5;
```

**PowerShell**

```powershell
'select * from person where age>18 order by name desc limit 5;' | surreal format -
```

```surql title="Output"
SELECT * FROM person WHERE age > 18 ORDER BY name DESC LIMIT 5;
```

`--write` has no file to write back to in this mode, so combining it with `-` reports `The --write flag cannot be used when reading from stdin.` and formats nothing.

## What the formatter changes

- **Keywords** are uppercased, and clauses left implicit in the source are written out.
- **Strings** are rewritten with single quotes, and identifiers that collide with a keyword are escaped in backticks.
- **Operators** get a space on each side, so `age>18` becomes `age > 18`.
- **Nested values** such as a multi-element array are broken across lines and indented with tabs.
- **Single-line comments** keep their text and are rewritten with a leading `#`, whichever of `#`, `--` or `//` the source used. Block comments written as `/* ... */` pass through unchanged.
- **Blank lines** between statements collapse to a single blank line.

Line structure between statements comes from the source. A statement spread over several lines is joined onto one, and two statements written on one line stay on that line, so the formatter does not impose one statement per line.

> [!WARNING]
> The formatter parses one statement at a time and treats the semicolon between statements as optional, so it accepts input that is not a valid query and rewrites it instead of reporting an error. `CREATE person WHERE;` is rejected by [`surreal validate`](/docs/reference/cli/surrealdb-cli/commands/validate.md), but `surreal format` turns it into ``CREATE person;`WHERE`;`` - two statements, with `WHERE` escaped as an identifier. Run `surreal validate` on a file before formatting it, and read the diff before committing a `--write`.

## Comparison with surqlfmt

[`surqlfmt`](/docs/reference/cli/formatter/overview.md) also formats SurrealQL, and the two tools are shipped and driven differently.

| | `surreal format` | `surqlfmt` |
| --- | --- | --- |
| Distribution | Part of the `surreal` binary | npm package `@surrealdb/surql-fmt` |
| Input | One file, or `-` for standard input | Paths and glob patterns, or `--stdin` |
| Format in place | `--write` | `--write` |
| Check without changing | | `--check` |
| Style options | | `--indent`, `--indent-char`, `--max-line-length` |

Reach for `surreal format` for a single file on a machine that already has the `surreal` binary, and for `surqlfmt` to sweep a tree of `.surql` files or to gate a CI job on formatting.

## Command help

To see the help information and usage instructions, in a terminal run the `surreal format --help` command without any further arguments. This command gives general information on the arguments, inputs, and additional options for the `format` command.

```bash
surreal format --help
```

The output of the above command:

```text
Format SurrealQL query

Usage: surreal format [OPTIONS] <FILE>

Arguments:
  <FILE>  Path to the SurrealQL file to format. Use dash - to read from stdin.

Options:
  -w, --write  Overwrite the file with the formatted output instead of printing to stdout.
  -h, --help   Print help

Logging:
  -l, --log <LOG>
          The logging level for the command-line tool [env: SURREAL_LOG=] [default: info] [possible
          values: none, full, error, warn, info, debug, trace]
      --log-format <LOG_FORMAT>
          The format for terminal log output [env: SURREAL_LOG_FORMAT=] [default: text] [possible
          values: text, json]
      --log-socket <LOG_SOCKET>
          Send logs to the specified host:port [env: SURREAL_LOG_SOCKET=]
      --log-file-level <LOG_FILE_LEVEL>
          Override the logging level for file output [env: SURREAL_LOG_FILE_LEVEL=] [possible
          values: none, full, error, warn, info, debug, trace]
      --log-otel-level <LOG_OTEL_LEVEL>
          Override the logging level for OpenTelemetry output [env: SURREAL_LOG_OTEL_LEVEL=]
          [possible values: none, full, error, warn, info, debug, trace]
      --log-socket-level <LOG_SOCKET_LEVEL>
          Override the logging level for unix socket output [env: SURREAL_LOG_SOCKET_LEVEL=]
          [possible values: none, full, error, warn, info, debug, trace]
      --log-socket-format <LOG_SOCKET_FORMAT>
          The format for socket output [env: SURREAL_LOG_SOCKET_FORMAT=] [default: text] [possible
          values: text, json]
      --log-file-enabled
          Whether to enable log file output [env: SURREAL_LOG_FILE_ENABLED=]
      --log-file-path <LOG_FILE_PATH>
          The directory where log files will be stored [env: SURREAL_LOG_FILE_PATH=] [default: logs]
      --log-file-name <LOG_FILE_NAME>
          The name of the log file [env: SURREAL_LOG_FILE_NAME=] [default: surrealdb.log]
      --log-file-format <LOG_FILE_FORMAT>
          The format for log file output [env: SURREAL_LOG_FILE_FORMAT=] [default: text] [possible
          values: text, json]
      --log-file-rotation <LOG_FILE_ROTATION>
          The log file rotation interval [env: SURREAL_LOG_FILE_ROTATION=] [default: daily]
          [possible values: daily, hourly, never]
```
