A minimal Obsidian plugin that allows you to push a configured folder from your vault to a specific folder in a GitHub repository using the GitHub API (no git required).
Perfect for syncing blog posts to Hugo or Jekyll GitHub Pages repositories.
- ✅ Manual sync via button press (no scheduling)
- ✅ GitHub API only (no git dependency)
- ✅ Always overwrite remote with local (local wins)
- ✅ Configurable source folder, target repo, and target folder
- ✅ Simple UI with settings tab and ribbon icon
I one-shot vibe-coded this plugin with Cursor CLI in about 5 minutes. I glanced through the code and tested it a little on Mac. Use it at your own risk.
This plugin is not intended for two-way syncing. It one-way pushes a folder of markdown files into a folder on git. I use this plugin alongside the official Obsidian Vault Sync.
- Download the latest release
- Extract the plugin folder to your vault's
.obsidian/plugins/directory. The .obsidian/plugins folder is inside your Obsidian vault, not a system-wide location. Each vault has its own.obsidianfolder. Find it in Obsidian: Settings → Community plugins → Installed plugins → Open plugins folder (or Settings → About → Open vault folder, then open.obsidian/plugins). - Reload Obsidian
- Enable the plugin in Settings → Community plugins
- Clone this repository
- Run
npm install - Run
npm run buildto build the plugin - Copy the plugin folder to your vault's
.obsidian/plugins/directory - Reload Obsidian
-
Get a GitHub Personal Access Token (PAT):
- Go to GitHub Settings → Developer settings → Personal access tokens
- Click "Generate new token (classic)"
- Give it a name (e.g., "Obsidian Blog Sync")
- Select the
reposcope - Generate and copy the token (starts with
ghp_)
Alternatively, create a fine-grained GitHub access token at https://github.com/settings/personal-access-tokens/new with "Contents" (Read and write) access to your specific blog repo.
-
Configure the Plugin:
- Open Obsidian Settings → GitHub Push Folder
- Enter your GitHub Personal Access Token
- Enter your repository owner (your GitHub username)
- Enter your repository name (e.g., "my-blog")
- Enter your source folder path (relative to vault root, e.g., "Blog Posts")
- Enter your target folder path (path in repo, e.g., "content/posts")
- Enter the branch name (usually "main" or "master")
- Click "Test Connection" to verify your settings
- Click "Save"
Screenshot of the setup I use for my Hugo blog hosted at https://github.com/richkuz/blog:
You can sync your folder to GitHub in three ways:
- Ribbon Icon: Click the cloud upload icon in the left ribbon
- Command Palette: Press
Cmd+P(Mac) orCtrl+P(Windows/Linux), then search for "Sync folder to GitHub" - Settings Tab: Click "Sync to GitHub" button in the plugin settings
- The plugin reads all files from your configured source folder (recursively)
- It fetches the current contents of the target folder from GitHub
- For each local file:
- If it exists in GitHub, it updates it
- If it's new, it creates it
- For each file in GitHub that doesn't exist locally, it deletes it
- Shows a notification with the results (created, updated, deleted counts)
- GitHub Personal Access Token: Your PAT with
reposcope - Repository Owner: Your GitHub username or organization
- Repository Name: The name of your GitHub repository
- Source Folder Path: Path in your vault (e.g., "Blog Posts")
- Target Folder Path: Path in the GitHub repo (e.g., "content/posts")
- Branch: GitHub branch to sync to (default: "main")
- Local Always Wins: The plugin always overwrites remote files with local files. No conflict resolution or merging.
- No Git Required: Uses GitHub API only, so you don't need git installed.
- File Size Limit: GitHub API has a 1MB limit per file. For larger files, consider using Git LFS or splitting files.
- Rate Limits: GitHub API has rate limits (5,000 requests/hour for authenticated users). The plugin will warn you if limits are low.
- Binary Files: Binary files (images, PDFs, etc.) are supported and will be base64 encoded.
- Verify your token is correct and starts with
ghp_orgithub_pat_ - Ensure your token has the
reposcope (for classic tokens), or "Contents" read and write (for fine-grained tokens) - Check that the token hasn't expired
- Verify the repository owner and name are correct
- Check that the repository exists and you have access
- Ensure the target folder path is correct (use forward slashes)
- Wait for the rate limit to reset (usually 1 hour)
- The plugin will show when the limit resets
- Check that the source folder path is correct
- Verify you have write access to the repository
- Check the Obsidian console (Developer Tools) for error messages
npm install
npm run buildnpm run devThis will watch for changes and rebuild automatically.
github-push-folder/
├── src/
│ ├── main.ts # Plugin entry point
│ ├── settings.ts # Settings interface
│ ├── github-api.ts # GitHub API client
│ ├── file-utils.ts # File utilities
│ ├── sync.ts # Sync logic
│ └── ui/
│ └── settings-tab.ts # Settings UI
├── styles.css # Plugin styles
├── manifest.json # Plugin manifest
└── package.json # Dependencies
MIT
Contributions are welcome! Please feel free to submit a Pull Request.

