Get AI summaries of any video or article — Sign up free
Obsidian October talks week 3: Use Plugin Settings + Creating theme for Obsidian 1.0 thumbnail

Obsidian October talks week 3: Use Plugin Settings + Creating theme for Obsidian 1.0

Obsidian·
5 min read

Based on Obsidian's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Define a typed settings object with sensible defaults so first-run behavior doesn’t depend on existing data.json.

Briefing

Obsidian 1.0’s biggest practical shift for plugin and theme builders is that customization now has a cleaner, more durable interface: plugins can persist user-facing settings through a formal settings tab and disk-backed data.json, while themes can be authored with far fewer brittle CSS selectors thanks to centralized variables and a new theme versioning system.

The stream’s first half walks through adding persistent settings to a plugin using a “spooky plugin” example. The workflow starts by defining a settings type (e.g., a single configurable string like “spooky text”) and providing defaults via a partial default settings object. Those defaults matter because users need sensible behavior on first run, before any saved configuration exists. The plugin then loads settings from the plugin’s data.json using Obsidian’s API: loadData pulls stored JSON into runtime, and the tutorial emphasizes merging it with defaults correctly. A key pitfall is avoiding accidental reference-sharing—updating the default object can unintentionally mutate the defaults themselves—so objectAssign is used to clone defaults first and then overlay saved values.

Once settings are loaded during plugin initialization, the plugin’s command/ribbon action can read from settings (e.g., showing the user-defined text instead of a hardcoded “boo”). The next step is wiring a UI: Obsidian’s PluginSettingTab is extended, and the tab is registered via addSettingTab. Inside the tab’s display method, the code builds HTML into the provided containerEl and uses Obsidian’s Setting API to create labeled controls with descriptions. A text field is bound to the settings value, and on change the plugin updates its in-memory settings and persists them back to disk using saveData. The result is tangible: disable and re-enable the plugin and the customized value reappears, confirming persistence.

The second half shifts from plugin settings to theme development with Kepano, focusing on how Obsidian 1.0 makes theming less selector-heavy and more future-proof. Previously, small UI tweaks often required digging through deeply nested DOM structures and writing narrow CSS selectors. Now, Obsidian exposes a large set of top-level CSS variables (around 400) that let theme authors control major interface elements directly with minimal CSS. That reduces maintenance burden—less code to keep consistent—and helps themes survive internal UI refactors because variable-based overrides don’t depend as tightly on DOM structure.

Theme versioning is the other major change. Themes now use the same versioning approach as plugins, including a minimum Obsidian app version compatibility field. This prevents older themes from being installed on incompatible Obsidian versions and allows the theme manager to serve the right updates over time.

To demonstrate the new approach, the stream starts with a CSS snippet (snippet.css) in the vault’s CSS Snippets folder, using Obsidian’s developer tools to inspect elements and identify the relevant variables. The example modifies inline title sizing and removes checkbox strike-through by overriding checklist done decoration. It then shows how color variables differ by light/dark mode using theme-light and theme-dark selectors, including the option to base a palette on “base colors” for faster theme creation. Finally, it turns the snippet into a full theme by creating a theme folder under .obsidian/themes, adding manifest.json and theme.css, and enabling the theme in Appearance settings. For sharing, themes are submitted via GitHub to Obsidian’s community theme index, with screenshots and repo references.

Together, the stream frames Obsidian 1.0 as a platform where user customization—whether through plugin settings or theme variables—becomes easier to build, easier to maintain, and less likely to break as Obsidian evolves.

Cornell Notes

Obsidian 1.0 streamlines customization by pairing persistent plugin settings with a more maintainable theming system. Plugin settings are defined with typed defaults, loaded from data.json via loadData, merged safely with defaults using objectAssign, and exposed through a registered PluginSettingTab using the Setting API. Changes made in the settings UI are saved back to disk with saveData, so user choices survive restarts. On the theming side, Obsidian 1.0 introduces centralized CSS variables (about 400) that reduce fragile, deeply nested selectors, plus theme versioning with a minimum compatible app version. Snippets can be promoted into full themes using manifest.json and theme.css, then shared through the community theme index on GitHub.

How does a plugin persist user-customizable settings in Obsidian 1.0, and why does default merging matter?

The plugin defines a settings type (for example, a configurable string like “spooky text”) and creates default settings using a partial default object so first-run behavior doesn’t break. At startup, it loads saved configuration from the plugin’s data.json using Obsidian’s loadData API. To avoid mutating the default object by reference, it merges defaults and saved data using objectAssign: an empty object is filled with default properties first, then overwritten by values from data.json. This ensures the defaults remain stable while user choices override them.

What is the minimal set of steps to expose plugin settings in the Obsidian UI?

A plugin must (1) extend PluginSettingTab, (2) implement the display method to render controls into containerEl, and (3) register the tab with addSettingTab. Inside display, the Setting API creates labeled inputs (e.g., a text field) with descriptions. The control’s onChange handler updates the plugin’s in-memory settings and triggers persistence via saveData.

Why does the tutorial insist on calling load settings during plugin load rather than only when a command runs?

The command/ribbon action reads from the plugin’s settings variable. If settings aren’t loaded before the user triggers the action, the command can’t reflect saved preferences. Loading settings during plugin initialization ensures runtime state is ready, so the UI action immediately uses the user-defined value instead of a hardcoded string.

What changed in Obsidian theming that reduces the need for brittle CSS selectors?

Obsidian 1.0 exposes a large set of top-level CSS variables (roughly 400) that map to major UI elements. Instead of hunting through a deeply nested DOM tree and writing narrow selectors for a single checkbox or heading, theme authors override variables directly. This cuts theme code size substantially (the stream cites around 80% less code for advanced themes) and makes themes more resilient to internal UI structure changes.

How does theme versioning work in Obsidian 1.0, and what problem does it solve?

Themes now use the same versioning model as plugins, including a minimum Obsidian app version field. That means older themes won’t be installed on incompatible app versions, and the theme manager can serve compatible updates over time. It also reduces confusion about what’s safe to update because compatibility is declared explicitly rather than inferred.

How do you turn a CSS snippet into a full theme in Obsidian 1.0?

Start with a snippet.css file in the vault’s CSS Snippets folder and verify changes using developer tools. Then create a theme folder under .obsidian/themes/<ThemeName>, add manifest.json (name, author, and minimum app version compatibility), and add theme.css containing the snippet’s CSS. After enabling the theme in Appearance settings, the snippet logic becomes a reusable theme package.

Review Questions

  1. When merging defaults with saved settings, what failure mode can happen if the plugin mutates the default settings object directly, and how does objectAssign prevent it?
  2. In the theming workflow, how do CSS variables and developer tools (inspector) work together to identify what to override without writing deep DOM selectors?
  3. What does the minimum app version field in a theme’s manifest.json protect users from, and how does it affect theme updates?

Key Points

  1. 1

    Define a typed settings object with sensible defaults so first-run behavior doesn’t depend on existing data.json.

  2. 2

    Load settings from the plugin’s data.json during plugin initialization using loadData, then merge with defaults safely via objectAssign.

  3. 3

    Expose settings through a registered PluginSettingTab and render controls using the Setting API bound to the plugin’s settings state.

  4. 4

    Persist user changes by updating in-memory settings on input change and calling saveData with the updated settings object.

  5. 5

    Use Obsidian 1.0’s centralized CSS variables (around 400) to avoid fragile, deeply nested CSS selectors.

  6. 6

    Adopt theme versioning with a minimum compatible Obsidian app version to prevent incompatible theme installs and enable correct updates.

  7. 7

    Prototype styling in a CSS snippet, then promote it to a full theme using manifest.json and theme.css under .obsidian/themes.

Highlights

Plugin settings become durable when loadData + saveData are wired to a settings tab, so user choices survive restarts.
objectAssign is used to clone defaults first, preventing accidental mutation of the default settings reference.
Obsidian 1.0’s theming shift replaces brittle DOM-targeting selectors with roughly 400 top-level CSS variables.
Theme versioning adds a minimum compatible app version, aligning theme compatibility with the plugin update model.
A practical path to theming starts with snippet.css, uses developer tools to find variables, then graduates into a full theme folder with manifest.json and theme.css.

Topics

  • Plugin Settings Persistence
  • PluginSettingTab UI
  • Theme Variables
  • Theme Versioning
  • CSS Snippets to Themes

Mentioned