# Frog, a Racket static site generator that now recommends against itself

> Frog generates a static site from Markdown or Scribble, with Bootstrap output and Pygments highlighting, and it is distributed as a Racket package. Its own README states that the project is in low-maintenance mode and that the author no longer uses it for his own blog, which is the single most useful thing a prospective user will read.

**greghendershott/frog** — Frog is a static blog generator implemented in Racket, targeting Bootstrap and able to use Pygments.

- Repository: https://github.com/greghendershott/frog
- Stars: 940 · Forks: 93
- Language: Racket
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/greghendershott-frog

## The README tells you not to expect much, and that is the honest summary

Frog is a static web site generator written in Racket. The workflow it describes is short: you write content in Markdown or Scribble, you generate files, and to deploy you push them to a GitHub Pages repo, or copy them to Amazon S3, or wherever you like.

The unusual part of the project is that its README spends most of its length on what Frog is not going to be. The author says he enjoyed working on Frog for many years, that in the beginning it was intended as a just-works simple application, and that he eventually stopped using it for his own blog. His own blog is now a Makefile driving a few pieces of code inherited from Frog, and he links to a write-up of that process.

He asks contributors to keep expectations aligned: issues about new features or off-label uses are welcome, but he does not expect much from them. He expects to still try to fix bugs when he has time and believes a fix would not create more or worse bugs.

He also names the date of that statement. Writing it in July 2019, he says the situation has been clear from the repo activity for a long time, and that he wants to be up-front so people can make an informed choice about how to spend their time. The repository was last pushed to on 2026-08-20, so the code has moved since that note without the project's stated posture changing.

For an evaluator, this is unusually good behaviour. A static site generator is the kind of project you adopt and then discover, two years later, that nobody has touched. Here you are told up front.

## Markdown and Scribble in, Bootstrap and Pygments out

The input side is Racket's own document formats. You write content in Markdown or Scribble, and Scribble is the language Racket's documentation system uses, so a Racket programmer can write a post in the same language they write documentation in.

The output side has two fixed choices. Pygments handles syntax highlighting for code blocks, and the generated site uses Bootstrap, which the README describes as responsive and automatically adapting to various screen sizes. That is a deliberate constraint. Frog is not a themeable framework with a plugin system; it produces a Bootstrap site with highlighted code, and what you can change is the content and the parts of the output you edit yourself.

Beyond posts, the README notes that you can also create non-post pages, so the site is not only a reverse chronological blog. Posts get a variety of automatic blog features, and the phrase is vague enough that you should read the full documentation for what those are.

The examples directory in the repository shows the layout the generator expects. It contains a frog.rkt configuration file, an info.rkt file, and separate directories for source, css, fonts, img and js. The presence of frog.rkt next to the content directories tells you configuration lives in a Racket file, which matches the README's account of the project evolving to use a `#lang` for configuration.

That evolution is the design story in miniature. Frog started as an application for non-Racket programmers, became more configurable, then adopted a `#lang`, and the author says at that point it felt more like what it really was, a tool for Racket programmers to do a static blog.

## Installation goes through raco, and the Makefile is the build manual

Frog ships as a Racket package, and the README badge points at the Racket package catalogue entry. The Makefile at the repository root makes the two supported installation paths explicit.

```bash
raco pkg install --deps search-auto
```

That is the install target, and the comment says it is primarily for use by CI. It installs dependencies as well as linking the package.

For day-to-day development there is a different target, which also builds docs if there are any and checks dependencies.

```bash
raco setup --tidy --avoid-main $(DEPS-FLAGS) --pkgs $(PACKAGE-NAME)
```

The package name is set at the top of the Makefile as PACKAGE-NAME=frog, and the dependency flags are folded into a variable called DEPS-FLAGS, so the two flags you see in the command are defined once and reused by the setup and check-deps targets. The remove target uninstalls it with raco pkg remove and the package name variable.

The test target runs the package tests with raco test -x -p, passing the package name variable, and the clean target uses raco setup --fast-clean to remove compiled artefacts and generated documentation.

The most interesting target is the one the project added for CI, named ci-extra-checks, which chains build-example and init-build. The build-example target builds the bundled example project and then checks a specific expected URI in the generated sitemap, a URL with a percent-encoded Unicode character in it. The init-build target creates a test-blog directory, runs raco frog --init, builds it, adds a new post with raco frog --new-markdown and another with raco frog --new-scribble, and builds again.

Those two targets are the closest thing to a specification of the command line interface, and they are what a new user should imitate.

## The command line interface, read off the Makefile

Because the README does not enumerate the commands, the Makefile is the practical source of truth for what the CLI can do. The flags visible there are worth listing as a set, since they map directly onto the workflow.

raco frog --init creates a new project in the current directory. That is the entry point for a new site, and the CI target uses it in a scratch directory before doing anything else.

raco frog --build generates the site. The example build runs it with --verbose --clean, and the --clean flag matters in practice because it removes previous output before regenerating, so a stale file from an earlier build does not linger in the published directory.

raco frog --new-markdown and raco frog --new-scribble create new posts, and they take a title as an argument. The CI target passes strings with non-ASCII characters to both, one using a lambda and one using accented letters, which is a deliberate check that the generator handles Unicode titles through the whole path rather than only in ASCII.

The output is checked too. The build-example target greps example/sitemap.txt for a specific percent-encoded URL, and the comment above it explains the reason: it verifies that an expected URI exists in the sitemap and is Unicode NFD normalized and percent-encoded. That is a precise statement of a real failure mode in static site generators, where a filename or URL can end up encoded differently depending on which normal form the file system or library used.

So the CLI has four verbs worth knowing: init, build, new-markdown and new-scribble, plus the verbose and clean flags. Anything beyond that is documented at the Racket documentation site the README links to.

## Where Frog is the wrong tool

The strongest reason not to use Frog is stated by its author, and it is not a technical objection. He no longer uses Frog for his own blog, preferring a Makefile driving a few pieces of code inherited from Frog. If the person who wrote the generator would rather maintain a handful of scripts, that tells you something about the maintenance surface of the generator itself.

The second reason is the audience. Frog is now a tool for Racket programmers who want a static blog. The original ambition was an application that non-Racket programmers might use, and the README says that did not happen. Configuration in Racket, a `#lang` for configuration, and a Racket package install are all fine if you write Racket and all friction if you do not.

The third reason is theme ownership. The generated site uses Bootstrap, and the repository has no separate theme system documented. If you need a design that matches a brand or a template you already own, you are editing generated output, and the upkeep lands on you.

A fourth practical point is the licence position. The README carries an MIT licence badge that points at a LICENSE file inside the frog directory, while the repository's own licence classification is not one the platform could determine. If you are shipping a generated site under a specific licence, check the file at frog/LICENSE directly rather than relying on a badge, and remember that the generated output embeds Bootstrap, whose licence travels with the output as well.

## The difference between Frog and a Makefile that calls a converter

The author describes the alternative he moved to, and it is more useful than a comparison with another blog generator because he actually adopted it. His own blog is a Makefile driving a few pieces of code inherited from Frog. The inheritance matters: the code that was worth keeping was kept, and the framework around it was dropped.

The difference in approach is about the location of the logic. Frog is an application that owns the pipeline: you call raco frog and it knows about the project layout, the sitemap, the page structure and the encoding rules. A Makefile approach inverts that. The Makefile owns the pipeline, and it calls individual pieces, each of which does one job and can be replaced. The frog directory in the repository still holds the source for the project, so the pieces remain available to a build that chooses to use them directly.

The frog.rkt configuration file in the example directory shows what the framework style costs. You describe the project in one place, and the generator reads it. The Makefile style moves that description into the build recipe instead, where it is mixed with the steps. Frog gives structure, the Makefile gives control, and the author decided the control was worth more.

For a newcomer this is the key decision, and it is cheaper to make before you have written ten posts than after. The same choice shows up in the tooling story, since Frog ships as a Racket package with its own build and test targets through the Makefile, so the package manager and the build system both have a say in what happens.

## A low-maintenance project with a permissive licence and a dated statement

The maintenance facts are plain. The repository is not archived, and the last push was on 2026-08-20. There are no GitHub releases for the project, so there is no tagged version history to pin against, and the version that a user gets is whatever the Racket package catalogue currently serves.

That last point is a real operational difference from a generator published as versioned releases on PyPI or npm. A Racket package install resolves through the package system, and the project itself carries UPGRADE.md and THANKS.md at the repository root, along with CONTRIBUTING.md. UPGRADE.md is the file to read first if you are moving an existing Frog site forward, because it is where the author would record what changed between versions of the generator.

The licence position needs care, as noted earlier. The README badge states MIT and points to frog/LICENSE, the licence classification on the repository side is not something the platform could categorise, and the project also credits an image used in the README under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic licence, so the frog picture itself carries a non-commercial condition even though the code does not.

The bottom line on maintenance is not the push date. It is the July 2019 statement in the README, which says the project is in low-maintenance mode, that the author expects to fix bugs when he has time, and that he no longer uses Frog for his own blog. The repository has seen commits since then, but nothing in the documentation revises that position.

## Conclusion

Adopt Frog if you are already a Racket programmer, want a small dependency footprint, and are content to own the generated site and its theme yourself. Do not adopt it if you need frequent upstream fixes, a maintained theme, or a generator that its own author would still choose for a new blog, because the README says plainly that the project is in low-maintenance mode and that the author replaced it with a Makefile for his own site. Before you start, read the UPGRADE.md file in the repository root and run raco frog --init in a scratch directory, then check whether the Bootstrap version the generated site targets still matches the one you want to ship.

## FAQ

### How do I install Frog?

Frog is a Racket package, so it is installed with raco pkg install --deps search-auto, which the Makefile lists as the install target and describes as primarily for use by CI. For day-to-day work there is a setup target built on raco setup.

### What command line options does raco frog support?

The Makefile in the repository uses raco frog --init, raco frog --build, raco frog --new-markdown and raco frog --new-scribble, together with the --verbose and --clean flags. The full documentation is hosted at docs.racket-lang.org/frog.

### Is Frog still maintained?

The README states the project is in low-maintenance mode and that the author expects to fix bugs only when he has time. The repository is not archived and the last push was on 2026-08-20, but the project has no GitHub releases.

### What output format does Frog produce?

The generated site uses Bootstrap, which the README describes as responsive, and Pygments handles syntax highlighting for code blocks. Content is written in Markdown or Scribble.

### Which licence does Frog use?

The README carries an MIT licence badge pointing at a LICENSE file inside the frog directory. The repository's own licence field is not one the platform could classify, so read frog/LICENSE directly.

## Sources

- [greghendershott/frog on GitHub](https://github.com/greghendershott/frog)
- [Issues](https://github.com/greghendershott/frog/issues)
- [README](https://github.com/greghendershott/frog/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/greghendershott-frog
