# Create Obsidian Vault

> Create a new Obsidian vault by copying a template .obsidian config (preserving its symlinks), scaffolding pages/journals/attachments folders, and initializing git — or reset an existing vault's config (theme, ribbon, Unique Note Creator settings, template symlink) back to these defaults without touching any content. Use when the user wants to "create a new vault", "新建一个 vault/Vault", "make an Obsidian vault", set up a project vault, or "恢复/reset an existing vault's settings to the default template".

- Skill: `goodluckz/create-obsidian-vault` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add goodluckz/create-obsidian-vault`
- Raw SKILL.md: https://api.skillmd.com/api/skills/goodluckz/create-obsidian-vault/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: goodluckz (https://skillmd.com/u/goodluckz)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/goodluckz/create-obsidian-vault

---


# Create Obsidian Vault

Scaffold a fresh Obsidian vault at a target path, cloning the user's shared `.obsidian`
config and initializing a git repo. Also supports resetting an **existing** vault's config
to these same defaults, without touching or deleting any existing content.

## Inputs
- **Target vault path** (required): where the vault root goes, e.g. `/Users/zhaoliang/Projects/foo`.
  If the user gives only a name, default the parent to `/Users/zhaoliang/LocalDocuments/vaults/`.
- **Source `.obsidian`** (optional): defaults to `/Users/zhaoliang/LocalDocuments/vaults/vault/.obsidian`
  (the user's template config). Confirm it exists before copying.

If the target path is ambiguous, ask the user before creating anything.

## Steps: creating a new vault

Run the bundled script with the target path:

```bash
bash ~/.claude/skills/create-obsidian-vault/create_vault.sh "<TARGET_VAULT_PATH>" ["<SOURCE_DOTOBSIDIAN>"]
```

Or do it manually:

1. `mkdir -p "$VAULT"`
2. Copy config preserving symlinks — **use `cp -R`, NOT `cp -RL`**:
   `cp -R "$SRC/.obsidian" "$VAULT/.obsidian"` (the template's `plugins`/`snippets`/`themes`/`hotkeys.json`
   are symlinks into a shared `obsidian-config` dir; `-R` keeps them as links so config stays shared).
3. Scaffold folders: `mkdir -p "$VAULT"/{pages,journals,attachments}` and `touch` a `.gitkeep` in each
   (git won't track empty dirs).
4. Symlink the vault-root `template/` folder (shared across vaults, needed by periodic-notes'
   `template/temp/...` daily/weekly/monthly templates):
   `ln -s /Users/zhaoliang/LocalDocuments/vaults/obsidian-config/TC-559_obsidian_template "$VAULT/template"`
   (absolute target, so it resolves no matter where the new vault lives).
5. Normalize the plugin/appearance config — same shared step as the restore flow below,
   see [Config normalization](#config-normalization-shared-step) for what it does:
   `bash ~/.claude/skills/create-obsidian-vault/normalize_vault_config.sh "$VAULT"`
6. Write `.gitignore` ignoring per-machine UI state and macOS cruft:
   ```
   .obsidian/workspace.json
   .obsidian/workspace
   .obsidian/workspace-mobile.json
   .obsidian/cache
   .DS_Store
   ```
7. `git init`, `git add -A`, initial commit.

## Steps: restoring defaults on an existing vault

For a vault that already exists (e.g. `/Users/zhaoliang/LocalDocuments/vaults/projects/cnsm-travel`)
and just needs its config reset to these same defaults — **without deleting or modifying any existing
notes/files**:

```bash
bash ~/.claude/skills/create-obsidian-vault/restore_vault_defaults.sh "<EXISTING_VAULT_PATH>"
```

This is non-destructive:
- `pages`/`journals`/`attachments`: created only if missing; existing folders and their contents are
  left completely alone.
- vault-root `template/` symlink: created only if missing.
- `zk-prefixer.json`, `appearance.json`'s `cssTheme`, and the left-ribbon `hiddenItems` in
  `workspace.json`/`workspaces.json`: these are config, not content, so they're always reset to
  defaults (see below) — this is the whole point of "restoring defaults".

It refuses to run if `$VAULT/.obsidian` doesn't exist (i.e. it's not an Obsidian vault at all) — it
never creates a `.obsidian` from scratch; use the create flow above for that.

### Config normalization (shared step)
Both flows call `normalize_vault_config.sh "$VAULT"`, which:
1. Pins the "Unique Note Creator" (zk-prefixer) plugin's per-vault settings — this file is a plain
   copy, not a shared symlink — to `$VAULT/.obsidian/zk-prefixer.json`:
   ```json
   {
     "template": "",
     "folder": "pages",
     "format": "YYYYMMDDHHmmss"
   }
   ```
2. Forces the built-in Default community theme (`cssTheme: ""`) in `$VAULT/.obsidian/appearance.json`,
   regardless of whatever theme the vault currently has active.
3. Trims the left ribbon to only: Thino, Git source control, Notebook Navigator, Open today (daily
   note), Open calendar — hides every other ribbon icon, in both `workspace.json` (live layout) and
   `workspaces.json`'s `"default"` saved layout.

## Why these choices
- **`cp -R` (not `-L`)**: preserves the shared-config symlinks. Dereferencing would copy the whole
  plugin/theme dirs and break the "install once, share everywhere" setup.
- **vault-root `template/` symlink**: not part of `.obsidian`, so `cp -R` doesn't create it — but
  periodic-notes' daily/weekly/monthly template paths (`template/temp/...`) need it at the vault root,
  same as MainVault. Absolute target like the `.obsidian` symlinks (see Caveat).
- **`zk-prefixer.json` overwrite**: unlike `plugins`/`snippets`/`themes`, this file is copied literally
  (not a symlink) — each vault has its own. The template vault's copy is tuned for its own layout
  (e.g. `thoughts` folder), so new vaults need it reset to `pages` + no template.
- **Left ribbon trim**: MainVault's ribbon accumulated icons from plugins that don't matter for a
  fresh project vault; a new vault only needs quick access to Thino, git sync, the notebook navigator,
  and today's daily note/calendar.
- **gitignore `workspace.json`/`workspace`**: these are single-machine UI layout state that change on
  every Obsidian open/close — committing them creates noisy diffs and multi-device conflicts. Keep
  `app.json`/`appearance.json`/`community-plugins.json` (real config) tracked.
- **`.gitkeep`**: preserves the empty `pages`/`journals`/`attachments` skeleton in git.

## Caveat
Git stores symlinks as their literal target path (an absolute path into `obsidian-config`). The repo
works on the **same machine**; pushing/cloning to a different machine will leave those symlinks dangling.
Mention this if the user plans to sync the repo across machines.

## Verify
After running, confirm: vault has `.obsidian` + `pages`/`journals`/`attachments`, a top-level `template`
symlink (`ls -la "$VAULT/template"`), `.obsidian` symlinks are still links
(`ls -la "$VAULT/.obsidian" | grep -E "plugins|themes|snippets|hotkeys"`),
`$VAULT/.obsidian/zk-prefixer.json` has `folder: "pages"`, empty `template`, `format: "YYYYMMDDHHmmss"`,
`$VAULT/.obsidian/appearance.json` has `cssTheme: ""`. For the create flow, also confirm git has an
initial commit. For the restore flow, run `git status` in the vault afterward and review the diff before
committing — `restore_vault_defaults.sh` never commits on its own.

