CLI tool
mazzzystar/tinymind avatar
mazzzystar/tinymind

tinymind: blogging straight into a GitHub repository

Tinymind - Write and sync your blog & thoughts with GitHub

806 stars63 forksTypeScriptMIT

At a glance

What is it?
tinymind turns a GitHub account into a blogging and note taking backend: it creates a public tinymind-blog repository in your account, commits every post to it, and serves a shareable page from a Cloudflare Worker. The CLI and a Chrome extension cover the two ways people actually write, and there is no server for the writer to run.
Who is it for?
tinymind fits a writer who is happy for their posts to live in a public GitHub repository and wants one command or one right click to publish, and it is the wrong tool for anyone whose notes must stay private, because the repository it creates is public and the privacy summary talks only about write access to public repositories.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 74 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The repository is the database

tinymind is described as turning your GitHub into a blog and memo data storage place with one-click sign in, and as needing no server because every input syncs to your GitHub repository.

The mechanism is the whole design, and it is worth being precise about it because the privacy story follows directly from it. You authorize tinymind to read and write your public GitHub repositories. It then creates a public repository named tinymind-blog in your account. When you write anything in tinymind, it commits to your own tinymind-blog repository. Your data is stored on your GitHub repository, separate from tinymind.

So there is no proprietary content store and no database to migrate. The blog is a Git repository of Markdown files, which means the things you already know about Git apply: the history is real, the files are readable, and you can clone the repository and edit it by hand if you want to.

The audience is people who write in short bursts and want to publish without a deployment pipeline. The site is at tinymind.me, a demo page lives at tinymind.me/mazzzystar, and there is a MacOS build packaged with Pake. The licence is MIT, the code is TypeScript, and the last push to the repository was on 2026-08-10, the same day the CLI was released as v0.1.0.

Three ways to write, one place to publish

The project ships three surfaces, and the reason is that the three habits of writing are different.

The web app at tinymind.me is the editor. The feature list records blog and thoughts support for Markdown, a feature letting writers manage their own blogs, meaning add, delete and edit posts, drag-and-drop image uploads, and shareable user main pages at a path such as tinymind.me/mazzzystar.

The Chrome extension, listed in the Web Store as Tinymind Quick Thoughts, is for capture. It gives you a quick popup editor with Markdown support, adds a right-click action on any selected text so you can add a quote to your thoughts from the page you are reading, accepts images by drag and drop or paste, and supports 20 languages. The extension was released as v1.0.0 in January 2026.

The command line tool is for publishing from a terminal, and the README is explicit that it exists so you can publish without cloning, running or deploying the tinymind website. It uses your existing GitHub CLI authentication and commits each successful command directly to your own tinymind-blog repository. The same program is available under three names, tinymind-cli, tinymind and the shorter tm.

The result is a coherent product: capture in the browser, write in the terminal, edit in the web app, and everything lands in the same repository that backs your public page.

The CLI is the fastest path to a published post

Installing the CLI and logging in to GitHub is the whole setup:

bash
npm install --global tinymind-cli
gh auth login

The gh auth login step is what removes the need for a token of your own, since the tool uses your existing GitHub CLI authentication.

From there, publishing is a single command. A short thought is the shortest form:

bash
tm "A quick thought"

An article with a title and a body uses the flags:

bash
tinymind -t "Article title" -c "Article body"

And a long article can be read from a file:

bash
tm -t "Long article" -f /path/to/article.md

If you do not want a global installation, the same thing runs through npx:

bash
npx --yes tinymind-cli "A quick thought"

One detail is worth knowing before you rely on the default. The default target repository is the authenticated user's tinymind-blog, and setting the TINYMIND_REPO environment variable overrides it with an owner/repo pair. That is what you want if you keep one repository for notes and another for the public blog, or if you want to publish into a repository that already exists.

The agent skill is a symlink and a package directory

There is an optional piece for AI agents, and it is described as optional for a reason: regular terminal users do not need it.

The npm package also contains a TinyMind skill for AI agents. To make it available to Codex, you link the installed package into the local skills directory and start a new Codex task:

bash
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
ln -s "$(npm root --global)/tinymind-cli" \
  "${CODEX_HOME:-$HOME/.codex}/skills/tinymind"

The mechanics are simple enough to be worth noting. The skills directory is created if it does not exist, the global npm root is where the installed package already lives, and a symbolic link makes the skill discoverable without copying anything. Nothing is uploaded and nothing is reinstalled.

The repository makes the same structure visible. There is a skills directory, and the package file carries an install script for the development version of the CLI, install:cli:dev, which installs the package from that local directory rather than from the registry. The test script runs the main test suite and then the CLI package tests separately, so both halves of the project are covered by one command.

The practical question for an adopter is whether you want an agent writing to your repository at all. If you do, the skill is already there and the setup is a symlink. If you would rather not have that, the skill is inert until it is linked, which is a reasonable default.

Cloudflare Workers, OpenNext and an R2 cache

The site itself runs on Cloudflare Workers, deployed through OpenNext, and the deployment section is short enough to read twice.

Production runs on the tinymind Cloudflare Worker, and pushes to main are built and deployed automatically by Cloudflare Workers Builds with these commands:

bash
npx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy

For a manual deployment, the README says to use npm run deploy, which the package file confirms runs the build and deploy steps in sequence. Runtime secrets are managed in Cloudflare and must not be committed to the repository, and OpenNext's incremental cache is persisted in a bucket named tinymind-opennext-cache on R2.

The application stack is Next.js, React, TypeScript, NextAuth.js for authentication, Tailwind CSS for styling, and Cloudflare Workers via OpenNext for the runtime. The dependency list in the package file shows the working set: Octokit for the GitHub API calls that create and commit to the repository, next-intl with an i18n directory and a messages directory for the internationalisation, react-markdown with remark-gfm, remark-math and rehype-katex for rendering posts including math, react-dropzone for the image uploads, zod for validation, and the usual set of Radix UI primitives.

There is a wrangler.jsonc for the Worker configuration, an open-next.config.ts for OpenNext, and a script called update-locales.sh for the translations.

The public repository is the constraint

Everything about this design flows from one decision, and the decision has a consequence that the privacy section does not highlight.

The privacy summary lists three things: your data is stored directly in your GitHub repository, tinymind is given only write access to public repositories, and you keep full control through your GitHub account. All three are true, and all three describe a public data store. The repository tinymind creates is described in the how it works section as a public repository named tinymind-blog, and that repository is where every post and every thought lands, with the site rendering it.

So tinymind is a publishing tool, not a notes tool. A private memo is not something the current flow supports, because the storage target is a public repository and the authorisation the app requests is scoped to public repositories. If you want a private journal, this is the wrong shape, and the fix would have to come from the project rather than from your configuration.

There is a second, softer constraint. The site that renders your posts is a Cloudflare Worker operated by the project, so the presentation layer, the URL scheme and the shareable page format are the maintainer's decisions rather than yours. The data is yours and portable, since it is Markdown in Git, but the way it looks is not.

And a third: the CLI authenticates through the GitHub CLI, so the tool inherits the permissions of your gh session, which is a large scope for something whose whole job is committing text files.

Editorial conclusion

tinymind fits a writer who is happy for their posts to live in a public GitHub repository and wants one command or one right click to publish, and it is the wrong tool for anyone whose notes must stay private, because the repository it creates is public and the privacy summary talks only about write access to public repositories. Verify first that you are content with the public repository, since that is where every post lands, and note that the site is a Cloudflare Worker rather than something you host, so the rendering layer is not yours to change.

Frequently asked questions

How do I publish a post with tinymind from the command line?

Install it with npm install --global tinymind-cli, run gh auth login, then use tm "A quick thought" for a short note, tinymind -t "Article title" -c "Article body" for a title and body, or tm -t "Long article" -f /path/to/article.md to read from a file. Without a global install, npx --yes tinymind-cli "A quick thought" does the same.

Where does tinymind store my posts?

In a public repository named tinymind-blog created in your GitHub account, and each write is committed to it automatically. Your data is stored on your GitHub repository separately from tinymind, and the site renders from there.

Can I publish to a different repository?

Yes. The default target is the authenticated user's tinymind-blog repository, and setting the TINYMIND_REPO environment variable to an owner/repo pair overrides it.

What does the tinymind Chrome extension do?

It captures thoughts and quotes from anywhere in the browser, with a quick popup editor that supports Markdown, a right-click action on selected text, image uploads by drag and drop or paste, and support for 20 languages.

How is the tinymind site hosted?

Production runs on the tinymind Cloudflare Worker, and pushes to main are built and deployed automatically by Cloudflare Workers Builds using npx opennextjs-cloudflare build and npx opennextjs-cloudflare deploy. Runtime secrets live in Cloudflare and the OpenNext incremental cache is stored in the tinymind-opennext-cache R2 bucket.

Official sources

  1. License: MIT
  2. mazzzystar/tinymind on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mazzzystar-tinymind.svg)](https://hysenlabs.com/projects/mazzzystar-tinymind)

Was this useful?