synvert-ruby: rewriting Ruby code with snippet rules instead of regexes
write snippet code to rewrite your project code
At a glance
- What is it?
- synvert-ruby is a command tool that rewrites Ruby source automatically by running named snippets, where a snippet is a small program written in a domain specific language rather than a regular expression. It ships with a catalogue of official snippets, can pull them from GitHub, and can generate new ones.
- Who is it for?
- synvert-ruby suits a team with a large Ruby codebase that has accumulated mechanical patterns worth changing, such as a deprecated factory syntax, and it is a better fit than a find and replace because a snippet understands the code it rewrites.
- 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 107 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Snippets are programs, not regular expressions
The project description is terse: write snippet code to rewrite your project code. The README expands it. synvert-ruby is a command tool to rewrite Ruby code automatically, and it depends on two other gems, synvert-core-ruby and synvert-snippets-ruby. The first provides a set of DSLs to rewrite Ruby code, and the second provides official snippets to rewrite Ruby code. That split is the design. Instead of a find and replace over text, a transformation is a small program written in a dedicated language that knows about Ruby syntax, so it can match a call in a context and rewrite it in a way a regular expression cannot express. The pattern is the same one that made automated refactoring tools in the JavaScript ecosystem popular, and the point of the DSL is that the transformation is written once, named, described, tested, and then applied across a repository. The homepage is synvert.net, and the topics are simply ruby and synvert.
Installing the gem and syncing the snippet catalogue
Installation is a gem install, and the README notes that this also installs synvert-core-ruby:
$ gem install synvertAfter that you can use synvert to rewrite Ruby code straight away, because Synvert is completely working with remote snippets on GitHub. If you would rather have the catalogue locally, the README says you can sync all official snippets locally to make it run faster:
$ synvert-ruby --syncThat distinction between remote and synced snippets is the one operational decision the README asks you to make. The official snippets are available on GitHub in the synvert-snippets-ruby repository and you can sync them any time you want, which means the catalogue is versioned outside the gem itself and can grow without a gem release. The price of that model is that a fresh install depends on network access to GitHub at run time, and a synced local copy trades that dependency for a stale catalogue you have to remember to refresh. The gem is MIT licensed, the repository carries a Gemfile, a Rakefile, a .rspec file, a Guardfile and a spec directory, and the top-level entries also include a Dockerfile, which is worth a separate look.
The command surface, and the flags that matter
The README documents the full help output, and it reads like a well-designed CLI rather than an accreted one. The verbs are list, query, show, open, generate, run, test, sync and execute. The two flags people will use constantly are scope control: --only-paths takes directories separated by comma, for example app/models,app/controllers, and --skip-paths takes file patterns separated by comma, for example vendor/ and a recursive glob over lib. On a real repository those two flags are the difference between a safe run and a rewrite of your vendored dependencies. There are also --show-run-process to print which files are being processed, --number-of-workers to test a snippet in parallel when the value is greater than 1, and two formatting preferences: --double-quote to prefer double quotes since single quote is the default, and --tab-width which uses 2 by default. The output format is selectable with -f, --format, and the listing example shows it used with a json value. The -r, --run flag accepts a snippet name such as ruby/new_hash_syntax, a remote url, or a local file path, which is what makes the tool composable with your own snippet collection.
Running a snippet, and where you point it
The run command takes a snippet and a project path, and the README shows the three ways to name a snippet. A named official snippet, with the project path as the second argument:
$ synvert-ruby -r factory_bot/use_short_syntax ~/Sites/synvert-hq/synvert-core-rubyA remote url, which points at the raw file in the snippets repository:
$ synvert-ruby -r https://raw.githubusercontent.com/synvert-hq/synvert-snippets-ruby/master/lib/factory_bot/use_short_syntax.rb ~/sites/synvert-hq/synvert-core-rubyOr a local file path:
$ synvert-ruby -r ~/.synvert-ruby/lib/factory_bot/use_short_syntax.rb ~/sites/synvert-hq/synvert-core-rubyThat last form is how you keep your own snippets in version control alongside the project, and it is the reason the tool has a local path input at all. The described behaviour of a run is to analyze and then rewrite code, which is the important word order. Synvert looks at the code before it changes it, and the -t, --test flag lets you see what a snippet would do without applying it, which is the flag to reach for first on a codebase you do not own.
Restricting the blast radius with path filters
Because a rewrite touches files, the two path flags are the part of the interface a careful operator uses first. Skipping paths looks like this:
$ synvert-ruby -r factory_bot/use_short_syntax --skip-paths vendor/ ~/sites/synvert-hq/synvert-core-rubyAnd narrowing to specific directories like this:
$ synvert-ruby -r factory_bot/use_short_syntax --only-paths app/models/ ~/sites/synvert-hq/synvert-core-rubyThe distinction between the two is worth being precise about. --only-paths selects where the snippet is allowed to act, and --skip-paths excludes places it must not touch. The README's own example of a skip pattern, a vendored directory and a recursive glob over lib, is a reminder of what lives in a typical Ruby repository: vendored code you did not write and do not want reformatted, and a lib directory whose files may be generated or shared. There is also --show-run-process to print the files being processed, which is the way to confirm your filters did what you meant before the rewrite lands:
$ synvert-ruby -r factory_bot/use_short_syntax --show-run-process ~/Sites/synvert-hq/synvert-core-rubyTogether with the -t test mode, that gives a review workflow: test, list the affected files, narrow the scope, then run.
Writing your own snippet, and describing an existing one
The tool expects you to write snippets, not just consume them. The -g, --generate flag creates a new snippet given a name, and the README's example names it ruby/convert_foo_to_bar, following the group/name convention that the -s flag also uses. The convention is not arbitrary. A snippet name is combined by group and name, for example ruby/new_hash_syntax, and that naming is what lets -l list everything, -q query a subset, -s show a description and -o open the file in your editor. The editor comes from ENV['SNIPPET_EDITOR'] or, failing that, ENV['EDITOR'], which means the open-a-snippet-in-your-editor flow works with whatever you already have configured. The -s flag is worth using before running anything, because it prints what the snippet does, and the -q flag lets you search the catalogue by keyword when you do not know the name of the transformation you want.
The Dockerfile, and what the repository does not say
The repository ships a Dockerfile, and it is short enough to read in full. It starts from ruby:4.0-alpine, installs git with apk, adds a random.org query as a cache-busting layer, runs gem install synvert, and sets the entrypoint to synvert-ruby. The git package is there because the tool talks to GitHub for remote snippets, and the random byte layer is there to invalidate the layer cache so the gem install actually reruns. That is the whole image, and it tells you the intended deployment shape: a throwaway container that runs a snippet against a mounted project. The repository layout is conventional for a gem, with bin/, lib/, spec/, a gemspec, a Rakefile and a Guardfile for the file-watching test loop, and the CHANGELOG.md at the root. Two things the documentation does not cover are worth flagging. The README does not document how a snippet is written in the DSL beyond pointing at the synvert-core-ruby repository, so the learning curve for authoring your own transformation sits in another repository. And the repository publishes no GitHub releases, with the last push on 2026-07-10, so the version you install from RubyGems and the version in this tree may not be the same.
Editorial conclusion
synvert-ruby suits a team with a large Ruby codebase that has accumulated mechanical patterns worth changing, such as a deprecated factory syntax, and it is a better fit than a find and replace because a snippet understands the code it rewrites. It is the wrong tool for one-off edits, where sed and a careful search are faster, and it is the wrong tool if you need to change behaviour rather than syntax, because a snippet rewrites code shape and cannot tell you whether the change is safe. Verify first that a snippet exists for the transformation you need, since the official catalogue lives in a separate repository and can be listed with synvert-ruby -l, and note that the repository publishes no GitHub releases while the last push was on 2026-07-10.
Frequently asked questions
How do I install synvert-ruby?
Run gem install synvert, which also installs synvert-core-ruby. The tool works with remote snippets on GitHub straight away, and synvert-ruby --sync pulls all official snippets locally so runs are faster.
How do I run a snippet against a project?
Use synvert-ruby -r with a snippet name and a project path, for example synvert-ruby -r factory_bot/use_short_syntax ~/Sites/synvert-hq/synvert-core-ruby. The flag also accepts a remote url or a local file path for the snippet itself.
How do I limit which files a snippet touches?
Use --only-paths to restrict the snippet to specific directories such as app/models, and --skip-paths to exclude directories and patterns such as vendor/ and a recursive glob over lib. The --show-run-process flag prints the files being processed.
What is the difference between the -t and -r flags?
The -t, --test flag tests a snippet, while -r, --run runs it, and the described behaviour of a run is to analyze and then rewrite code. Testing first shows what a snippet would change before it changes anything.
Can I write my own snippet?
Yes. The -g, --generate flag creates a new snippet from a name following the group and name convention, such as ruby/convert_foo_to_bar. The DSLs used to write snippets are provided by the separate synvert-core-ruby repository.
Official sources
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.
[](https://hysenlabs.com/projects/synvert-hq-synvert-ruby)Was this useful?