INI Input

Formatted INI

Success
Warning

Why an INI formatter usually costs you the comments

Pull the php.ini out of any container image and count the lines. Thousands of them, and most start with a semicolon — the shipped configuration file is a manual with a few active settings scattered through it. A long-lived .gitconfig is the same, and so is a systemd unit where every directive has a line above it naming the incident that put it there. In INI, the commentary usually outweighs the configuration.

Which is what makes the obvious approach wrong. Parse the file into an object, print the object back with tidy spacing — that is how the JSON, XML and YAML formatters on this site work, and it is right for all three. Run it on INI and the file comes back neat and stripped. Push this page’s sample through the ini package on npm and you get six comments in, zero out, [sim.batch] relocated to the bottom, and the quotes gone from "SIM_LTE_V4". None of that is a library bug: a parser returns a value, a comment is not part of a value, and key order in a plain object was never a promise.

So this page never parses your file in order to reformat it. It rewrites the source text and touches only what is safe to touch — the spaces around =, leading indentation, trailing whitespace, runs of blank lines, the gap before a section header. Comments keep their marker, their wording and their position, trailing ones included. Anything the scanner cannot classify is copied out byte for byte and counted, because a formatter that mangles input it did not expect is worse than one that admits it left a line alone.

Then the result is proved before you see it. Both versions are read into their sections, keys and values and compared, the comment count going in is compared with the count coming out, and either check disagreeing throws the formatted text away rather than showing it. A formatter may change how a file looks; it must never change what the file says. That guard is what earns the tidying its licence to be thorough.

One caveat, and it belongs to the format rather than to this page. INI has no specification — the nearest thing to one mostly catalogues how the dialects differ. "The same document" here means the same under the npm package’s reading, which is the most widely deployed one. Where your parser disagrees, the Python question below is the disagreement most likely to bite you.

Tidying a file

  1. Paste or drop the file inA whole php.ini, a .gitconfig, a tox.ini, an exported .conf, or a fragment out of a wiki. Nothing is uploaded — these files carry database passwords and registry tokens often enough that sending one anywhere would be a poor default.
  2. Pick how the separator sitsSpaced writes key = value, which is what hand-written INI looks like. Aligned pads the keys so the equals signs form a column. Tight writes key=value — what serialisers emit, and what you want if the file is going back into one.
  3. Add indentation or blank-line tidyingIndenting puts entries two spaces under their header. It is purely for the reader: a key belongs to whichever [section] was opened last and leading whitespace is discarded, so indentation carries no meaning at all. Blank-line tidying collapses runs of empty lines to one and puts a single blank line before each header.
  4. Read the chips, then copyThe green chip counts the comments in the output, so it is a measurement rather than a promise. Beside it sit the section and key totals, plus — only when there is one — a count of lines passed through untouched because they were not a comment, a header or a key.

If the file is heading back into a tool that rewrites it, format it Tight with indentation off. Most INI writers emit key=value flush left, so matching that shape means the next automated write produces a one-line diff instead of a whole-file one. Save Aligned for the file a person is about to read.

A provisioning config that three people have edited

Every line below is valid and the loader reads it fine — it has simply drifted, the way a config does when it is edited under time pressure. Watch the two comment markers and the trailing note on auth_type: they come out the other side unchanged.

drifted → tidy every comment survives
as found4 comments
; Bulk SIM provisioning - ticket NET-2291
[operator]
name     = Linnea Mobile
mcc=234
country   =GB


[apn]
; IMS APN stays separate - merging broke VoLTE
name = internet.linnea.gb
auth_type = PAP        ; CHAP is unsupported here
qci=9

[timeouts]
# Under 15000 trips the retry storm
attach_ms   = 30000
auth_ms=15000
formatted, alignedthe same 4 comments
; Bulk SIM provisioning - ticket NET-2291

[operator]
name    = Linnea Mobile
mcc     = 234
country = GB

[apn]
; IMS APN stays separate - merging broke VoLTE
name      = internet.linnea.gb
auth_type = PAP  ; CHAP is unsupported here
qci       = 9

[timeouts]
# Under 15000 trips the retry storm
attach_ms = 30000
auth_ms   = 15000

When this is the tool you want

Making a config diff about the change you made

You added one setting to a .gitconfig and your editor re-indented half the file on save. Format both revisions the same way before committing and the review is about the setting rather than the whitespace, with the comments explaining the existing entries still in place. Skim Git’s own account of the file syntax first — subsection headers like [remote "origin"] are a Git extension, not something every INI reader understands.

Reading configuration you did not write

A settings file arrives from a vendor or a container and it is a wall of keys with no blank lines and inconsistent spacing. Tidying it is the cheapest way to see its shape before deciding what to change. For structure rather than text, INI to Table lays the sections out as a grid and INI to JSON gives you something queryable.

Cleaning up machine-written INI

Anything a script serialises tends to be correct and unreadable: no blank lines, no grouping, keys in whatever order the writer produced. This gives it the spacing a hand-written file would have had, without you editing something that was already right and introducing a typo.

Checking a file before you trust it

Formatting will not tell you a key is defined twice, or that a header is missing its closing bracket, or that a byte order mark is making your first lookup fail. Those are the things that make a file read one way to a person and another way to a parser, and INI Validator reports them with line numbers. Run that when a file misbehaves; run this one when it works and is merely unpleasant.

What it does

  • Keeps every comment — whole-line and trailing, in position, with its original ; or # marker. The file is never round-tripped through a parser, so there is nothing to lose them in.
  • Proves its own output. Sections, keys and values are compared before and after, and so are the comment counts. Either check failing withholds the result.
  • Aligns per run, not per section. A comment or blank line between two groups lets each group line up on its own longest key, so one long outlier cannot push an unrelated group across the pane.
  • Passes through what it does not recognise, unchanged and counted, rather than reshaping a line into whatever it guessed the line meant.
  • Honours escaped markers. A value such as C:\logs\#archive keeps its escaped # — otherwise the formatter would truncate a Windows path the parser reads whole.
  • Leaves values alone. Quoting, case and digits are re-emitted as written, so a 19-digit ICCID or a zero-padded reference code survives intact.
  • Runs in the tab. Config files hold credentials; nothing is sent anywhere.

Questions that come up

Will my comments really all survive?

Yes, and the chip counts them in the output so you are not taking it on trust. The reason is structural rather than clever: the source text is edited in place and never rebuilt from a parsed value. For contrast, push any commented INI file through a parse-and-print round trip — the result is tidy, correct, and completely stripped.

INI has no standard, so what does "the same document" mean?

The same sections, keys and values under this site’s reading, which follows the npm package. Your parser may read the same bytes differently, and Python is the sharpest example: configparser ships with inline_comment_prefixes set to None, so on Python 3.11 the line auth_type = PAP ; CHAP unsupported yields the value 'PAP ; CHAP unsupported' — the note is part of the string. Reformatting normalises the spaces in front of that semicolon, which is invisible under most readings and a changed value under that one. If a file is destined for configparser, keep trailing comments out of it; they were never comments there.

Why did one line come back exactly as it was?

It was not a comment, not a section header, and had no = in it, so there was nothing to normalise without inventing a meaning for it. Those lines are emitted byte for byte and counted in a chip. Usually it is a bare flag key, a fragment from a bad copy-paste, or a syntax extension belonging to whichever tool owns the file.

Why does alignment stop at a comment?

On purpose. Alignment is computed over each run of consecutive entries rather than over a whole section, so a comment or a blank line starts a new group. Padding an entire section to one distant outlier — a forty-character connection_string above four short keys — leaves a lake of whitespace that reads worse than no alignment at all. People already group these files; alignment follows the grouping.

My value has a hash in it. Will it be cut off?

Not if it is escaped the way your parser expects, which is \# or \;. The trailing comment is found using exactly the escape rules the parser uses, so spool = C:\logs\#archive stays whole. Inconsistency here would be the worst kind of bug on this page: the formatter would truncate a path the parser reads in full, and the two would quietly disagree about the file.

It says the check failed and gave me nothing.

That is the guard working. The formatted text is read back and compared against the original, and a mismatch discards it rather than showing it — handing you a file that means something slightly different is far worse than handing you nothing. Your input is untouched in the left pane. If you hit this, the file is worth keeping: it is a case the formatter should handle and does not.

Related tools

Worth reading

  • EditorConfig – An INI-shaped file your editor already reads, and a compact example of how far the format stretches
  • systemd unit file syntax – One dialect written down properly, including why a line continuation changes what a comment means