Scrap is the way

Scrap is the way


Updated on

The Story of Scrap

My coding journey began with Scratch, an intuitive platform that introduced me to the world of programming. Yet, as I ventured into JavaScript, I faced a formidable challenge. While Scratch had provided a solid foundation, the transition to JavaScript felt like a daunting leap. This challenge ignited the idea for Scrap, a tool designed to simplify the transition from block-based programming to JavaScript.

Download Scrap

Features

  1. Block-based coding – While Scrap encourages the transition to text-based programming, it supports both block and text editors.
  2. Strongly typed – In the text editor, Scrap supports TypeScript type annotations, which provide type safety. In the block editor, Scrap won’t allow you to connect blocks with incompatible types.
  3. Blocks ⇆ Code – Scrap allows you to convert blocks to code and vice versa. This feature is especially useful for learning JavaScript syntax.
  4. No VM, no interpreter – Scrap compiles your code to JavaScript, which means that you can run it anywhere, without Scrap.
  5. HTML output – Scrap allows you to export your code as HTML, which means that you can share your projects with anyone, anywhere.
  6. Open-source – Scrap is open-source, which means that you can contribute to it and make it better.

Code × Text

ScrapScript is a code name for the problem of the incompatibility. It aims to design an ECMAScript subset, which can be converted to blocks and back as easy as possible.

It’s been obvious since the very beginning that ScrapScript needs to be typed, as not all blocks are compatible by shape. Previously, this was handled via JSDoc but when the Monaco Editor was introduced in Scrap 4, TypeScript was way more helpful.

However, not all JavaScript features will be supported. Classes, symbols, regular expressions, modules, sets & maps, undefined, template literals, and many more…

And some equivalent features lose their different syntax when converted. An example might be:

object.toString();
// After conversion to blocks and back
String(object);

Thanks to #158, I realised that Date.prototype.getTime() can be implemented.

// These are equivalent:
object.valueOf();
Number(object); // default Scrap syntax
+object;
object.getTime(); // for dates, #158

The inspiration

The name Scrap is a combination of the words Scratch and Snap, two block-based programming languages that inspired me to create Scrap. Snap gave me an idea to make the IDE advanced and powerful, while Scratch inspired me to make it intuitive and easy to use.

Under the hood

The technology

Scrap is coded with Rust, TypeScript, and Sass.

Scrap consists of HTML frontend and Rust backend. The Rust backend handles the underlying logic, and also the compilation of user code to JavaScript, with the help of SWC. The frontend is built with TypeScript and Sass and uses Blockly as a block editor. The code editor is powered by Monaco Editor.

Scrap uses technology based on BlockLike.js as an engine (not VM).

Scrap engine and SWC

Scrap Engine is based on BlockLike.js; these days, the code bases are totally different, and the features differ as well.

As Scrap doesn’t have a VM, somehow it needs to delay block execution (like Scratch does), and control code execution. The compiler handles most of that, but still, some things must be done at runtime – setters, getters, and throwing uncatchable errors do the job.

Scrap comes up with a SWC plugin, which provides users better coding experience, as their code can be less ugly. That means, if one includes Scrap Engine and uses just the code written in IDE, it won’t work.

Let’s see how the engine and SWC cooperate:

  • Async / await
    • Scrap Engine’s methods are asynchronous
    • In IDE, users don’t even notice, as SWC adds the necessary keywords
  • Setters / getters
    • Scrap Engine needs to have methods instead of getters and setters (self.getX() and self.setX(10)
    • In IDE, users use the more familiar syntax: self.x = 10
  • Control flow
    • When the Scrap engine needs to, or is told to stop the project, it throws Scrap.StopError
    • SWC makes sure users cannot catch the error, as this would lose the effect
  • On-screen variables
    • Scrap engine allows to have Scratch-like on-screen variables
    • SWC allows users to declare them inside the Variables interface and rewrites the setters and getters
  • SWC also handles the conversion between blocks and text

Monaco Editor

Monaco Editor is extended, so it provides:

  • TypeScript IntelliSense tied to the Scrap environment
  • warning about the block-incompatible syntax
  • color pickers when using Scrap’s color functions
  • syntax highlighting mirrors the block colors

Conclusion

Scrap is a tool that simplifies the transition from block-based programming to JavaScript. It is designed to be intuitive and easy to use, while also providing advanced features for more experienced users. Scrap is open-source, which means that you can contribute to it and make it better. If you are interested in contributing to Scrap, please get in touch with me.

© 2025 Tomáš Wróbel.