Here are the most important features that differentiate Jay from other REPL's:
require modules directly from the registry
Eager eval (requires
node >= 12.3.0)
Typeahead + dropdown menu-style completion
- Colored input
- Bracket/quote pair completion
- Full readline keybindings support
- Lazy loaded built-in modules
Jay was created with two goals in mind:
awaitand typeahead code completion
It would probably make sense to split Jay into separate packages (just the REPL into one, and the smart
require into another) in the future, to allow better reusability of the REPL components.
Basic web scraping
Let's say that for some reason we want to scrape all of the titles and links from the hacker news front page.
Let's begin by running Jay and getting the necessary dependencies:
> const got => const cheerio =
Then, we download the page and load the HTML into cheerio:
> const body = await> const $ = cheerio
$ behaves pretty much like jQuery, we can use the following simple one-liner to get our result:
text: 'National Park Typeface'link: ''...
After running the previous line, we can store the result in a named variable via
_ - which caches the result of the last evaluation - as follows:
> const result = _> resultlength // 30
If you find an interesting example to put in this section, a PR is more than welcome!
Jay expects itself to be installed globally:
$ npm install -g jay-repl
Then simply run it by typing
jay in the terminal:
Alternatively, Jay can be directly run with Node builtin
$ npx -p jay-repl jay
How does the smart
require function work?
After pressing enter in the prompt, Jay parses the entered input into an AST using acorn and looks for all
CallExpression's whose names are equal to
This triggers the "asker" system to ask the user whether they actually want to install a given
require'd module. If the user decides to install the module, Jay starts a "global"
npm install in its cache directory. If they don't, nothing happens and the evaluation will most likely result in an "module not found" error.
Either way, after all of the above is complete, the control is handed back to the evaluator which only now actually executes the entered line.
How does Jay's
require differ from the normal one?
require only looks for modules within two places:
- locally, if the module id is prefixed with things like
require in addition to the above also looks within its global cache (but only if the local &
node_modules resolutions fail). This, in addition to parsing the input and looking for
require calls, allows for importing any module that's on the registry, automatically installing it if needed.
require also is also a "fresh
What does "fresh
require function in Jay doesn't use the standard node's cache and always reads the files from disk upon importing them. Consider the following example:
Let's say we have a file called
greet.js with the following contents:
module 'hello '
node's repl, require it, and we get the expected output:
> greet =>// 'hello hello '
Now, without closing the session, we change the file into:
-module.exports = x => 'hello '.repeat(x)+module.exports = x => 'hi '.repeat(x)
Requiring the file again will, unfortunately, not change the output:
> greet =>// 'hello hello hello '
Jay, as beforementioned, doesn't cache modules. Repeating the steps yields the result we actually want in this case:
$ jay$ echo "module.exports = x => 'hello '.repeat(x) > greet.js"
> greet =>// 'hello hello '
$ sed -i 's/hello/hi/' greet.js
// (in the same Jay session)> greet =>// 'hi hi hi '
This also works analogically with modules in
node_modules, Jay's cache, JSON files, etc.
Where does Jay store the cached modules?
Jay uses env-paths to determine the cache's location:
- MacOS -
- Linux -
- Windows -
You can see the exact location of the cache by simply running the following line in Jay:
- Fork & clone the repository
- Start the Typescript watch script:
$ npm run build:watch
- Make your changes
- Try out your changes on your local build
$ node dist/cli.js
- Run the tests:
$ npm test
- Commit & PR!
This repository uses Git LFS for storing readme's gifs, if you want to view them locally you will need to install and set up the Git LFS extension on your machine.
MIT © nikersify