# obsidian-style-settings: the manifest says MIT and the platform says GPL

> An Obsidian plugin that turns CSS comments into a settings pane, so a theme author can expose their variables without writing any interface code. It is a small, well-specified idea with a thoroughly documented format. Its manifest is where it goes wrong, and the format documentation contradicts itself about how many setting types there are.

**community-archive/obsidian-style-settings** — A dynamic user interface for adjusting theme, plugin, and snippet CSS variables within Obsidian

- Repository: https://github.com/community-archive/obsidian-style-settings
- Stars: 2,518 · Forks: 180
- Language: TypeScript
- License: GPL-3.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/community-archive-obsidian-style-settings

## Three files disagree about the licence

The plugin's package manifest declares a permissive open-source licence in its own licence field.

The platform's view of the repository records something different entirely, and the licence file at the root of the tree matches the platform rather than the manifest.

The manifest also carries an empty author field and an empty keyword list, which suggests it is maintained in a fairly hands-off way. That is a plausible explanation for how a licence field drifted out of sync with the repository without anyone noticing: the manifest is not the file anyone reads to decide the terms, and the file everyone does read is the licence file at the root.

It is still a problem, because the manifest is what tooling reads. Any script that scans a package's declared licence to build an inventory, run a policy check, or produce an attribution notice will get the wrong answer, and it will get it confidently rather than falling back to the repository.

For a plugin distributed through a community plugin directory, the terms most people actually rely on are the ones in the repository. Confirm which applies before you redistribute anything derived from it.

## The introduction counts seven setting types and then documents nine

The reference section opens by saying each setting definition must be separated by a dash, and that there are seven setting types. Then it lists seven.

The sections that follow document nine of them.

The two that are in the list of seven and documented with their own heading and example are the informational text type and the class selection type. Both appear below as full reference sections with their own prose and code samples, and both have attributes the list never mentions: the informational one has a markdown flag that determines whether its description is rendered, and the class selection one has an empty-option allowance that determines whether a default is mandatory.

So the count of seven is wrong, and it is wrong in the specific way that matters: it is the list of seven that a reader would use as a checklist when writing a settings block, and the two types missing from it are the two with conditional requirements. A theme author working from the checklist would produce a settings file that the plugin renders differently from what they expected, with no error, because both of those types do exactly what they say when used correctly.

The prose under the list is also self-contradictory in a small way. It describes the class selection type as creating a dropdown for a CSS variable, when the variable-specific heading below describes it as adding classes to the body element, which is what its sibling toggle type does. The wording has drifted from the behaviour.

## The type's identifier becomes the class or variable name, which is the whole design

Once you understand the naming rule, the rest of the format follows from it, and it is the part worth understanding before you write anything.

For the class toggle type, the identifier you choose in the settings file is used as the class name that gets added to or removed from the body element. For the text, number, number slider, selection, and colour types, the identifier is used as the CSS variable name.

That means your settings file is not metadata about a stylesheet. It is the stylesheet's interface, and the identifier is the contract between the two. Rename an identifier in the settings block and every rule in the snippet or theme that references that variable or class silently stops matching.

The toggle type also has an optional flag that adds a command to the application, so the same toggle can be flipped from the keyboard or the command palette rather than only from the settings pane. That is the one place where the identifier leaks out of CSS and into the application's own command surface.

The colour type carries a format attribute in the example that splits the hue from the saturation and lightness, which is a convenience for producing a palette rather than a single colour, and the slider and plain number types differ only in the control shown to the user.

## The manifest is versioned by the plugin, the format by nothing

The manifest's version field is behind the newest published release. The release list shows a newer version than the one in the manifest, which means the manifest in the repository is either the state before a release was tagged or the version string was bumped and the tag was pushed at a different time.

Neither of those is a bug on its own. What it does mean is that the manifest is not a reliable indicator of what someone installing from the directory will get, and that the release list and the manifest should be read together.

The bigger question is how the format itself is versioned. Settings are defined in comments inside CSS files, and the plugin scans the snippet, theme, and plugin directories of a vault's configuration directory for those comments. Every one of those three directories belongs to something else: a snippet is a user file, a theme is third-party, a plugin is third-party. So the plugin is parsing YAML out of files it did not write, in a format that has no version field.

The consequence is that the format has an implicit version equal to whatever the plugin last shipped, and it can change under a set of stylesheets that nobody re-tested. That is a real constraint on anyone maintaining themes for this editor, and the reference documentation does not mention it.

## A colour picker is pulled from a tarball URL on a fork

One runtime dependency is not a published package. It is an archive URL, pointing at a repository that is a fork of another, pinned to a specific commit hash.

So the colour picker this plugin uses to render its colour settings comes from a tarball of a commit on a fork, and there is no package name and no version number for it. It will not be updated by installing a newer release of the plugin, and it will not be resolved by any registry lookup a dependency audit performs.

This is the standard way to depend on something that has not been published, and it is not unusual in the plugin ecosystem. It is worth naming because of what it costs rather than what it does: the build is not reproducible from the manifest alone in the sense that a reader would assume, a security scanner has nothing to match against, and the reason for the fork is not explained anywhere in the file.

The rest of the runtime dependencies are ordinary published packages, including one YAML parser, one colour library, an indentation detector, a fuzzy sorting library, an environment file loader, and type definitions for two of them.

## The release process is three scripts chained by hand

The scripts section describes the whole release as a sequence, and it is worth reading because it is unusually explicit about the fact that a human runs each step.

The first script takes the commits since the most recent tag and writes them to a release notes file, then stages that file. The second runs a version bump script, stages the manifest and the versions file, and then runs the first. The third commits using the version string as the commit message, creates a tag with that same string, and pushes both the branch and the tags.

So the process is: generate notes, bump the version, commit, tag, push. The version in the tag and the version in the commit message and the version in the manifest are all the same string, which is a nice property, and the third script achieves it by reading it out of the environment rather than from a file.

Two details are worth noting. The notes script depends on the previous tag existing, so the first release from a fresh clone would fail at that step. And the third script runs two pushes, which means a partially completed release is possible where the commit is on the branch and the tag is not.

Neither matters much for a plugin. It does mean the release is one person at a terminal with no automation, which is the sort of thing that becomes load-bearing as a project grows contributors.

## The feature list omits the most interesting part of the format

The feature summary at the top of the readme lists two capabilities: toggling classes on and off the body element, and setting numeric, string, and colour CSS variables.

That is three items covering seven types, and it leaves out two things that the rest of the document treats as first class.

The first is that settings blocks can be nested. The heading type creates a collapsible section with a level between one and six and an optional collapsed flag, which means a large theme can present its settings as a tree rather than a flat list of forty controls. For a theme with many variables that is the difference between a usable settings pane and a wall.

The second is the informational text type, which renders arbitrary text and optionally interprets it as Markdown. That turns the settings pane into a place to put documentation, and a theme author can therefore explain what a control does in the same file that defines it.

Neither is hard. Both are the kind of thing a plugin's own README would lead with if the summary were written by someone who had built a theme with it.

## Conclusion

This is the right tool for the job and the format is unusually well specified, so if you write themes or snippets for this editor it is worth learning. Two things to check first. The licence is inconsistent between the manifest and the repository, so confirm the terms directly rather than relying on either. And the format is versioned by whatever the plugin last scanned, not by the plugin version, which means an upgrade can change what your existing stylesheets do to settings you never edited. Read the type reference rather than trusting a count, because the count in the introduction is wrong and the sections that follow it disagree with each other.

## FAQ

### What does obsidian-style-settings do?

It lets snippet, theme, and plugin CSS files declare their own configuration options through comments containing YAML, and renders all of them in one settings pane. Settings can toggle classes on the body element or set numeric, string, and colour CSS variables, and it scans the snippets, themes, and plugins directories under a vault's configuration directory.

### How do I define a setting in obsidian-style-settings?

Add a comment beginning with `@settings` to a CSS file, containing YAML with `name`, `id`, and `settings`. Each setting is separated by a dash and needs at least an `id`, a `title`, and a `type`, with `description` optional.

### How many setting types does obsidian-style-settings have?

The introduction says seven and lists seven, but the reference section documents nine, adding an informational text type and a class selection type with their own headings and examples. Both of the extra types carry conditional requirements the list does not mention.

### What licence is obsidian-style-settings under?

The sources disagree. The package manifest declares MIT, while the repository is recorded under a copyleft licence and the licence file at the root matches that. Confirm the applicable terms with the project before redistributing anything derived from it.

### What does the setting identifier do in obsidian-style-settings?

For class toggle settings it becomes the class name added to or removed from the body element. For the text, number, number slider, selection, and colour types it becomes the CSS variable name, so renaming an identifier breaks every rule that referenced it.

## Sources

- [community-archive/obsidian-style-settings on GitHub](https://github.com/community-archive/obsidian-style-settings)
- [Issues](https://github.com/community-archive/obsidian-style-settings/issues)
- [License: GPL-3.0](https://github.com/community-archive/obsidian-style-settings/blob/main/LICENSE)
- [README](https://github.com/community-archive/obsidian-style-settings/blob/main/README.md)
- [Releases](https://github.com/community-archive/obsidian-style-settings/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/community-archive-obsidian-style-settings
