seanpmaxwell/code-divider

For inserting region and section dividers in your development files. Works great in the command line.

TypeScript

1

20 commits

updated Sep 18, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

If you organize your code with comment separators, checkout code-divider (r/typescript)

This is more of a personal preference thing, but I like to code in a top-down format, and because of the way hoisting works in TypeScript/JavaScript. I separate my files into regions in this order: *Constants -> Types -> Classes (if any) -> Functions -> Export*. To keep these regions…

0

Sep 18, 2026

README

code-divider

NPM Version NPM Downloads License CI

code-divider turns simple comment markers into tidy, centered region/section dividers. No counting = signs. No lining things up by hand.

Use it from the command line, run it automatically when you save, or call it from your own code.

👀 Preview

code-divider inserting two region headers and a section header

🧭 Table of contents

🚀 Quick start

Add a marker on its own line in a source file:

// @reg utilities

// @sec helper functions

Then run (inside of your project folder):

npx code-divider

Your markers are replaced in place with formatted headers. That’s it!

You can target a file or a folder. Folders are searched recursively.

npx code-divider --path ./src --dry-run

📌 Markers

There are two kinds of dividers:

MarkerCreates
// @reg LabelA three-line boxed region header.
// @sec LabelA single-line section header.

Use your language’s comment syntax:

// @sec helper functions
# @sec helper functions
/* @sec helper functions */

By default, region labels become UPPERCASE and section labels become Capitalized Words. You can customize both in Configuration.

Built-in support includes JavaScript, TypeScript, Java, CSS, SCSS, C, C++, Go, Rust, PHP, Ruby, Python, Bash, and SQL. You can add more languages through the configuration file.

💻 Command-line options

npx code-divider [options]

With no options, code-divider processes the current directory.

OptionWhat it does
-p, --path <path>Process a file or directory. Defaults to the current directory.
-c, --config <file>Use a specific config file. Its settings override the built-in defaults.
-d, --dry-runList the files that would change without writing anything.
--checkLike --dry-run, but exit with code 1 if any file would change. Useful for CI and pre-commit hooks.
-i, --init [dir]Create a default code-divider.config.json in the given directory, or the current directory if omitted. Runs on its own without processing source files.
-h, --helpShow help.
-v, --versionShow the version.

A few examples:

# Process the current directory
npx code-divider

# Process one file
npx code-divider --path ./src/index.ts

# Check for changes in CI without modifying files
npx code-divider --check

# Use a specific config file
npx code-divider --config ./custom.config.json

💾 Run on save

This is my favorite way to use code-divider: write a marker, hit save, and let your editor handle the rest.

If your editor supports running commands on save, configure it to run npx code-divider.

For VS Code, install the Run on Save extension and add this setting to your settings.json:

{
  "emeraldwalk.runonsave": {
    "commands": [
      {
        "match": "\\.(css|js|jsx|ts|tsx)$",
        "cmd": "npx code-divider"
      }
    ]
  }
}

🧩 Divider anatomy

Here’s a section divider, shortened for readability:

// ============== My Section ============== //

These are the names used throughout the configuration:

TermMeaning
MarkerThe token that requests a divider: @reg or @sec.
CommentThe comment syntax used to write the marker, such as //, #, or /* ... */.
LabelThe title after the marker, such as My Section.
Filler characterThe repeated character that fills the available space: = in this example.
BookendsThe strings at the start and end of each generated line: "// " and " //" here.

🔧 Configuration

The defaults work out of the box. Add a config file only when you want to make the dividers your own.

Create a config file

Start with a file containing all the default settings:

npx code-divider --init

This creates code-divider.config.json in the current directory. It won’t overwrite an existing file.

To create it somewhere else:

npx code-divider --init ./packages/app

How config files are found

Unless you pass --config <file>, code-divider checks locations in this order:

  1. The target directory, or the containing directory if the target is a file.
  2. The directory the command is run from.

The first config file found wins. These config files are not merged together.

Settings in the selected config file override the built-in defaults. Anything you leave out keeps its default value. If no config is found, the built-in defaults are used.

Shared settings

The All key contains settings shared by every language:

SettingWhat it controlsDefault
CharacterLimitThe column that generated header lines extend to.79
FillerCharacterThe character used to fill the header lines."="
RegionLabelFormatHow region labels are capitalized."uppercase"
SectionLabelFormatHow section labels are capitalized."capitalize"

Both label-format settings accept:

ValueExample
"uppercase"my cool sectionMY COOL SECTION
"lowercase"My Cool Sectionmy cool section
"capitalize"my COOL sectionMy Cool Section
"none"Leave the label exactly as written.

Words that start or end with a non-alphanumeric character are left unchanged under every format. That keeps labels containing things like @decorator or .foo intact.

Language-specific settings

Other than All and filter, top-level config keys can be any string value, they're just there for organization. You can use a built-in key to customize that language's current settings, or a new key to add your own.

SettingWhat it controls
ExtensionsFile extensions to match, without the leading dot. For example, ["py"].
CommentA [start, end] pair describing the comment syntax used for markers. Use "" as the end for line comments.
BookendsOptional [start, end] strings for generated header lines. Defaults to Comment; for line comments, the opener is mirrored on the right. For example, "# " becomes ["# ", " #"].
CharacterLimitOverride All.CharacterLimit for this language. Note that this DOES account for indentation. So the divider will stop at the value regardless of where the marker starts.
FillerCharacterOverride All.FillerCharacter for this language.
RegionLabelFormatOverride All.RegionLabelFormat for this language.
SectionLabelFormatOverride All.SectionLabelFormat for this language.

For example:

{
  "All": {
    "CharacterLimit": 100,
    "FillerCharacter": "-"
  },
  "Java": {
    "Bookends": ["// ", " //"]
  },
  "Python": {
    "Extensions": ["py"],
    "Comment": ["# ", ""]
  }
}
// Main.java
class Main {

    // ===================================================================== //
    //                               FUNCTIONS                               //
    // ===================================================================== //

    public static void main(String[] args) {
        System.out.println("Hello code-dividers");
    }
}
# Main.python

# =========================================================================== #
#                                  CONSTANTS                                  #
# =========================================================================== #

print('Hello code-divider')

Default Settings

These are the language keys, file extensions, and comment styles available by default.

Config keyFile extensionsMarker exampleGenerated bookends
JavaScript.js .jsx .ts .tsx .mjs .cjs// @reg Label"// "" //"
Java.java// @reg Label"// "" //"
Css.css .scss/* @reg Label */"/* "" */"
C.c .h// @reg Label"// "" //"
Cpp.cpp .cc .cxx .hpp .hh .hxx// @reg Label"// "" //"
Go.go// @reg Label"// "" //"
Rust.rs// @reg Label"// "" //"
Php.php// @reg Label"// "" //"
Ruby.rb# @reg Label"# "" #"
Python.py .pyi .pyw# @reg Label"# "" #"
Bash.sh# @reg Label"# "" #"
Sql.sql-- @reg Label"-- "" --"

Filtering files

Use the top-level filter key to choose which files get processed.

Patterns work like include and exclude in a tsconfig.json. They are relative to the folder being processed.

SettingWhat it does
includeProcess only matching files. Defaults to [], which uses the default recursive search.
excludeSkip matching files and folders. Your list replaces the built-in exclusions. Use [] to exclude nothing.

Filters select the files to consider, but to be updated those files still need to match a configured language extension.

In case you're wondering why I didn't use Node's built-in fs.glob function, it's only available in Node 22+ and marked experimental until Node 24.

Default exclusions

Out of the box, code-divider skips:

  • At any depth: node_modules, .vscode, .idea, .claude, and files ending in .log or .json.
  • At the top level: bin, lib, and dist.

💻 Programmatic use

import { insertCodeDividers } from 'code-divider';

const updatedFiles = await insertCodeDividers('targetPath', options?)

targetPath can be a file or directory. Relative paths are resolved against options.cwd.

All options are optional:

OptionWhat it doesDefault
cwdBase directory for resolving relative paths.process.cwd()
configFilePathUse a specific config file. If empty, check the target directory, then cwd, then use the built-in defaults.''
isDryRunReturn the files that would change without writing them.false
loggerHandle messages with an object exposing info and warn methods, such as console.Console output
silentSuppress all messages. Takes priority over logger.false

The logger receives:

  • info messages, such as which config file is being used.
  • warn messages, such as a marker with no label.

📄 License

MIT © seanpmaxwell

Contributors

seanpmaxwell

20 commits

seanpmaxwell/code-divider

For inserting region and section dividers in your development files. Works great in the command line.

TypeScript

1

20 commits

updated Sep 18, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

If you organize your code with comment separators, checkout code-divider (r/typescript)

This is more of a personal preference thing, but I like to code in a top-down format, and because of the way hoisting works in TypeScript/JavaScript. I separate my files into regions in this order: *Constants -&gt; Types -&gt; Classes (if any) -&gt; Functions -&gt; Export*. To keep these regions…

0

Sep 18, 2026

README

code-divider

NPM Version NPM Downloads License CI

code-divider turns simple comment markers into tidy, centered region/section dividers. No counting = signs. No lining things up by hand.

Use it from the command line, run it automatically when you save, or call it from your own code.

👀 Preview

code-divider inserting two region headers and a section header

🧭 Table of contents

🚀 Quick start

Add a marker on its own line in a source file:

// @reg utilities

// @sec helper functions

Then run (inside of your project folder):

npx code-divider

Your markers are replaced in place with formatted headers. That’s it!

You can target a file or a folder. Folders are searched recursively.

npx code-divider --path ./src --dry-run

📌 Markers

There are two kinds of dividers:

MarkerCreates
// @reg LabelA three-line boxed region header.
// @sec LabelA single-line section header.

Use your language’s comment syntax:

// @sec helper functions
# @sec helper functions
/* @sec helper functions */

By default, region labels become UPPERCASE and section labels become Capitalized Words. You can customize both in Configuration.

Built-in support includes JavaScript, TypeScript, Java, CSS, SCSS, C, C++, Go, Rust, PHP, Ruby, Python, Bash, and SQL. You can add more languages through the configuration file.

💻 Command-line options

npx code-divider [options]

With no options, code-divider processes the current directory.

OptionWhat it does
-p, --path <path>Process a file or directory. Defaults to the current directory.
-c, --config <file>Use a specific config file. Its settings override the built-in defaults.
-d, --dry-runList the files that would change without writing anything.
--checkLike --dry-run, but exit with code 1 if any file would change. Useful for CI and pre-commit hooks.
-i, --init [dir]Create a default code-divider.config.json in the given directory, or the current directory if omitted. Runs on its own without processing source files.
-h, --helpShow help.
-v, --versionShow the version.

A few examples:

# Process the current directory
npx code-divider

# Process one file
npx code-divider --path ./src/index.ts

# Check for changes in CI without modifying files
npx code-divider --check

# Use a specific config file
npx code-divider --config ./custom.config.json

💾 Run on save

This is my favorite way to use code-divider: write a marker, hit save, and let your editor handle the rest.

If your editor supports running commands on save, configure it to run npx code-divider.

For VS Code, install the Run on Save extension and add this setting to your settings.json:

{
  "emeraldwalk.runonsave": {
    "commands": [
      {
        "match": "\\.(css|js|jsx|ts|tsx)$",
        "cmd": "npx code-divider"
      }
    ]
  }
}

🧩 Divider anatomy

Here’s a section divider, shortened for readability:

// ============== My Section ============== //

These are the names used throughout the configuration:

TermMeaning
MarkerThe token that requests a divider: @reg or @sec.
CommentThe comment syntax used to write the marker, such as //, #, or /* ... */.
LabelThe title after the marker, such as My Section.
Filler characterThe repeated character that fills the available space: = in this example.
BookendsThe strings at the start and end of each generated line: "// " and " //" here.

🔧 Configuration

The defaults work out of the box. Add a config file only when you want to make the dividers your own.

Create a config file

Start with a file containing all the default settings:

npx code-divider --init

This creates code-divider.config.json in the current directory. It won’t overwrite an existing file.

To create it somewhere else:

npx code-divider --init ./packages/app

How config files are found

Unless you pass --config <file>, code-divider checks locations in this order:

  1. The target directory, or the containing directory if the target is a file.
  2. The directory the command is run from.

The first config file found wins. These config files are not merged together.

Settings in the selected config file override the built-in defaults. Anything you leave out keeps its default value. If no config is found, the built-in defaults are used.

Shared settings

The All key contains settings shared by every language:

SettingWhat it controlsDefault
CharacterLimitThe column that generated header lines extend to.79
FillerCharacterThe character used to fill the header lines."="
RegionLabelFormatHow region labels are capitalized."uppercase"
SectionLabelFormatHow section labels are capitalized."capitalize"

Both label-format settings accept:

ValueExample
"uppercase"my cool sectionMY COOL SECTION
"lowercase"My Cool Sectionmy cool section
"capitalize"my COOL sectionMy Cool Section
"none"Leave the label exactly as written.

Words that start or end with a non-alphanumeric character are left unchanged under every format. That keeps labels containing things like @decorator or .foo intact.

Language-specific settings

Other than All and filter, top-level config keys can be any string value, they're just there for organization. You can use a built-in key to customize that language's current settings, or a new key to add your own.

SettingWhat it controls
ExtensionsFile extensions to match, without the leading dot. For example, ["py"].
CommentA [start, end] pair describing the comment syntax used for markers. Use "" as the end for line comments.
BookendsOptional [start, end] strings for generated header lines. Defaults to Comment; for line comments, the opener is mirrored on the right. For example, "# " becomes ["# ", " #"].
CharacterLimitOverride All.CharacterLimit for this language. Note that this DOES account for indentation. So the divider will stop at the value regardless of where the marker starts.
FillerCharacterOverride All.FillerCharacter for this language.
RegionLabelFormatOverride All.RegionLabelFormat for this language.
SectionLabelFormatOverride All.SectionLabelFormat for this language.

For example:

{
  "All": {
    "CharacterLimit": 100,
    "FillerCharacter": "-"
  },
  "Java": {
    "Bookends": ["// ", " //"]
  },
  "Python": {
    "Extensions": ["py"],
    "Comment": ["# ", ""]
  }
}
// Main.java
class Main {

    // ===================================================================== //
    //                               FUNCTIONS                               //
    // ===================================================================== //

    public static void main(String[] args) {
        System.out.println("Hello code-dividers");
    }
}
# Main.python

# =========================================================================== #
#                                  CONSTANTS                                  #
# =========================================================================== #

print('Hello code-divider')

Default Settings

These are the language keys, file extensions, and comment styles available by default.

Config keyFile extensionsMarker exampleGenerated bookends
JavaScript.js .jsx .ts .tsx .mjs .cjs// @reg Label"// "" //"
Java.java// @reg Label"// "" //"
Css.css .scss/* @reg Label */"/* "" */"
C.c .h// @reg Label"// "" //"
Cpp.cpp .cc .cxx .hpp .hh .hxx// @reg Label"// "" //"
Go.go// @reg Label"// "" //"
Rust.rs// @reg Label"// "" //"
Php.php// @reg Label"// "" //"
Ruby.rb# @reg Label"# "" #"
Python.py .pyi .pyw# @reg Label"# "" #"
Bash.sh# @reg Label"# "" #"
Sql.sql-- @reg Label"-- "" --"

Filtering files

Use the top-level filter key to choose which files get processed.

Patterns work like include and exclude in a tsconfig.json. They are relative to the folder being processed.

SettingWhat it does
includeProcess only matching files. Defaults to [], which uses the default recursive search.
excludeSkip matching files and folders. Your list replaces the built-in exclusions. Use [] to exclude nothing.

Filters select the files to consider, but to be updated those files still need to match a configured language extension.

In case you're wondering why I didn't use Node's built-in fs.glob function, it's only available in Node 22+ and marked experimental until Node 24.

Default exclusions

Out of the box, code-divider skips:

  • At any depth: node_modules, .vscode, .idea, .claude, and files ending in .log or .json.
  • At the top level: bin, lib, and dist.

💻 Programmatic use

import { insertCodeDividers } from 'code-divider';

const updatedFiles = await insertCodeDividers('targetPath', options?)

targetPath can be a file or directory. Relative paths are resolved against options.cwd.

All options are optional:

OptionWhat it doesDefault
cwdBase directory for resolving relative paths.process.cwd()
configFilePathUse a specific config file. If empty, check the target directory, then cwd, then use the built-in defaults.''
isDryRunReturn the files that would change without writing them.false
loggerHandle messages with an object exposing info and warn methods, such as console.Console output
silentSuppress all messages. Takes priority over logger.false

The logger receives:

  • info messages, such as which config file is being used.
  • warn messages, such as a marker with no label.

📄 License

MIT © seanpmaxwell

Contributors

seanpmaxwell

20 commits

Languages

TypeScript

99.4%