Welcome to Ripen, a stack-based scripting engine with highly readable syntax, that can be implemented with little code and effort in a reasonably high-level host language. It's informed by RetroForth and PostScript, but diverges from either in important ways, not least due to its string-threaded nature.

Ripen is based on principles explained in the article More About Tiny Scripting Engines. The point is having a single-file engine, easily copy-pasted into any application. For this reason, the default vocabulary is kept small. See the language overview for more details, but for a quick start try:

	( Hello, world! ) .. cr
	3 2 + 3 2 * < . cr

(In the web version, nothing is printed out until you use cr.)


11 February 2024
Ripen JS was updated to use modern Javascript features.
The C++ port is now mirrored on Codeberg.
20 July 2023
Version numbers were unified across ports, and compatibility improved.
2 March 2023
C++ port has been refreshed and relicensed.
1 March 2023
Nim port has been revived and relicensed; see below.
10 February 2022
Ripen was ported to C++ as "version 2.0".
20 December 2021
There's now an offshoot called Guava, by eli.
11 May 2021
Ripen (1.0) is used as the scripting language of Tipsy Turtle.


C++ port version 4.1b (2024-02-27); Boost Software License:

Version 4.0 brought numerous breaking changes. Please check documentation. Older versions:

All archives include documentation + examples. Other ports:

Building and running

Ripen has multiple implementations; notes and/or build scripts are included with each source archive.

Binaries are built on a Debian 10 machine, and seem to have decent compatibility with other / older distributions. No promises.


An informal test was performed with a modified version of the Rugg/Feldman benchmarks (#5), ported like this (yep, it's a one-liner):

:nop ; { $i 2 / 3 * 4 + 5 - =a nop } 1000 times $a . cr

Results are as follows:

While timings for this are hard to get on a modern PC, the Nim port seems faster than Python 2.7, and even Tcl. Of course, both are much more complex.

Differences between versions

In the JS port, everything goes on the stack: numbers, strings and lists / code blocks. In the native ports, lists and strings go to their own memory areas. Hence extras like the ? sigil used to show the definition of a user-defined word, and .. to print out the contents of the scratch pad.

In the JS and Vala ports, aliases are much more powerful. They can contain arbitrary code. They're still only expanded once.

The Nim port defines included right inside the library.

The JS port has alert, confirm and prompt words, but not included or bye.

Frequently Asked Questions

What do you have against parsing words?
Nothing at all! My very first Forth interpreter, that I made in 2009 for a tutorial, had parsing words and even quoted strings. This time I simply wanted to try something different after seeing RetroForth.
Does Ripen count as single-file anymore? The C++ code consists of two files.
The library proper is still just one file, ripen.hpp; the other one is a demo driving app so you can see that it works, and how to use it in your own projects.


Next minor goal: improve documentation;

Long-term plan: find ways to make the language more useful.


Questions and feedback are welcome. All archives include contact information. See my homepage as well.

If you like Ripen, please see on the blog for how to support me.