Skip to main content

Rebranding the Editor

You probably want to give your mod a unique look, here are some things you can do to do that.

warning

To an extent, you must rebrand your mod as you can't use Scratch's trademarks. Scratch's trademarks are things like the name Scratch, their logos and their mascots (like Scratch Cat and Gobo). However, you should be fine giving credit to Scratch.

Scratch Terms of Service quote

7.3 Scratch Team Marks. You may not use any tradenames, trademarks, logos, or other marks owned or controlled by the Scratch Team, including, but not limited to, the Scratch Cat, the Scratch logo, ScratchJr, Giga, Nano, Pico, Terra, Milli, and Zepto (collectively, the “Scratch Team Marks”) except solely for your personal, educational, and non-commercial purposes in direct connection with your use of the Service to create and share Scratch projects as otherwise permitted herein. Any commercial use of the Scratch Team Marks will be subject to the terms of a separate license agreement negotiated between you and the Scratch Team, if any, provided that the Scratch Team is not obligated to grant any rights or licenses for any commercial use and may deny a license request for any or no reason in the Scratch Team’s sole discretion. You acknowledge that we are the sole owner of the Scratch Team Marks and any and all goodwill associated therewith. You agree that you will not do anything inconsistent with such ownership and that all use by you of the Scratch Team Marks will inure to the benefit of the Scratch Team. You agree further that nothing in these Terms will be construed as granting to you any right, title or interest in the Scratch Team Marks, other than the right to use the Scratch Team Marks as expressly provided in these Terms. You agree that you will not contest, oppose, or challenge our ownership of or title to the Scratch Team Marks or contest, oppose or challenge the validity of the Scratch Team Marks. You further agree that you have no power or right to and will not during the term of these Terms or thereafter contest, oppose or challenge the title or any rights of the Scratch Team in or to the Scratch Team Marks, alone or with other elements; claim any right, title, or interest in or to the Scratch Team Marks, alone or with other elements adverse to the Scratch Team; or register or apply for registration of the Scratch Team Marks anywhere, alone or with other elements. You agree that your use of any Scratch Team Marks permitted under these Terms or pursuant to any separate license will comply with any guidelines provided by Scratch to you. You agree that you will cease all uses of Scratch Team Marks immediately upon the Scratch Team’s request that you cease such uses and the Scratch Team will have no liability to you for your being required to cease such use. You hereby assign and will assign in the future to us all rights you may acquire by operation of law or otherwise in the Scratch Team Marks, including all applications or registrations therefor, along with the goodwill associated therewith.

You can change the logo by replacing the SVG located at scratch-editor/packages/scratch-gui/src/components/menu-bar/scratch-logo.svg.

Changing the default project (including Scratch Cat)

The default project is located at scratch-editor/packages/scratch-gui/src/lib/default-project.

FileFormatContents
0fb9be3e8397c983338cb71dc84d0b25.svgSVG Imagecostume2 (Scratch Cat)
83a9787d4cb6f3b7632b4ddfebf74367.wavWave Soundpop
83c36d806dc92327b9e7049a565c6bff.wavWave SoundMeow
bcf454acf82e4504149f7ffe07081dbc.svgSVG Imagecostume1 (Scratch Cat)
cd21514d0531fdffb22204e0ec5ed84a.svgSVG Imagebackdrop1
index.tsJavaScriptList of contents of the project.
project-data.tsJavaScriptContains the project.json.

Changing the colours

Scratch's colours are defined in scratch-editor/packages/scratch-gui/src/css/colors.css. Below is a table of all the colours and a screenshot of the editor showing an example of where that colour is used. These screenshots do not include all uses of the colour.

Variable NameDefault ValueUsage Screenshot
$ui-primary
hsla(215, 100%, 95%, 1)Screenshot
$ui-secondary
hsla(215, 75%, 95%, 1)Screenshot
$ui-tertiary
hsla(215, 50%, 90%, 1)Screenshot
$ui-motion-overlay
hsla(215, 100%, 65%, 0.9)Screenshot
$ui-white
hsla(0, 100%, 100%, 1)Screenshot
$ui-white-dim
hsla(0, 100%, 100%, 0.75)Screenshot
$ui-white-transparent
hsla(0, 100%, 100%, 0.25)Screenshot
$ui-transparent
hsla(0, 100%, 100%, 0)Screenshot
$ui-black-transparent
hsla(0, 0%, 0%, 0.15)Screenshot
$text-primary
hsla(225, 15%, 40%, 1)Screenshot
$text-primary-transparent
hsla(225, 15%, 40%, 0.75)Screenshot
$motion-primary
hsla(215, 100%, 65%, 1)Screenshot (also loading screen)
$motion-tertiary
hsla(215, 60%, 50%, 1)Unused
$looks-primary
hsla(260, 60%, 60%, 1)Screenshot
$looks-transparent
hsla(260, 60%, 60%, 0.35)Screenshot
$looks-light-transparent
hsla(260, 60%, 60%, 0.15)Screenshot
$looks-secondary-dark
hsla(260, 42%, 51%, 1)Screenshot
$red-primary
hsla(20, 100%, 55%, 1)Screenshot
$red-tertiary
hsla(20, 100%, 45%, 1)Screenshot
$sound-primary
hsla(300, 53%, 60%, 1)Screenshot
$sound-tertiary
hsla(300, 48%, 50%, 1)Screenshot
$control-primary
hsla(38, 100%, 55%, 1)Screenshot
$data-primary
hsla(30, 100%, 55%, 1)Screenshot
$pen-primary
hsla(163, 85%, 40%, 1)Screenshot
$pen-transparent
hsla(163, 85%, 40%, 0.25)Screenshot
$pen-tertiary
hsla(163, 86%, 30%, 1)Screenshot
$error-primary
hsla(30, 100%, 55%, 1)Screenshot
$error-light
hsla(30, 100%, 70%, 1)No screenshot.
$error-transparent
hsla(30, 100%, 55%, 0.25)Screenshot
$extensions-primary
hsla(163, 85%, 40%, 1)Screenshot
$extensions-tertiary
hsla(163, 85%, 30%, 1)No screenshot.
$extensions-transparent
hsla(163, 85%, 40%, 0.35)No screenshot.
$extensions-light
hsla(163, 57%, 85%, 1)No screenshot.
$drop-highlight
hsla(215, 100%, 77%, 1)Screenshot

Changing the project file extension

There are a few places you need to change to adjust the project file extension.

  • scratch-editor/packages/scratch-gui/src/containers/sb3-downloader.jsx
    const getProjectFilename = (curTitle, defaultTitle) => {
    let filenameTitle = curTitle;
    if (!filenameTitle || filenameTitle.length === 0) {
    filenameTitle = defaultTitle;
    }
    return `${filenameTitle.substring(0, 100)}.sb3`;
    };
    Adjust the .sb3 with your own extension.
  • scratch-editor/packages/scratch-gui/src/lib/sb-file-uploader-hoc.jsx
    createFileObjects () {
    // redo step 7, in case it got skipped last time and its objects are
    // still in memory
    this.removeFileObjects();
    // create fileReader
    this.fileReader = new FileReader();
    this.fileReader.onload = this.onload;
    // create <input> element and add it to DOM
    this.inputElement = document.createElement('input');
    this.inputElement.accept = '.sb,.sb2,.sb3';
    this.inputElement.style = 'display: none;';
    this.inputElement.type = 'file';
    this.inputElement.onchange = this.handleChange; // connects to step 3
    document.body.appendChild(this.inputElement);
    // simulate a click to open file chooser dialog
    this.inputElement.click();
    }
    Add your extension to the list of accepted extensions.
  • scratch-editor/packages/scratch-gui/src/lib/sb-file-uploader-utils.js
    export const getProjectTitleFromFilename = fileInputFilename => {
    if (!fileInputFilename) return '';
    // only parse title with valid scratch project extensions
    // (.sb, .sb2, and .sb3)
    const matches = fileInputFilename.match(/^(.*)\.sb[23]?$/);
    if (!matches) return '';
    return matches[1].substring(0, 100); // truncate project title to max 100 chars
    };
    You will need to adjust the regular expression used. Here is a template you can use: /^(.*)\.(sb[23]?|YOUR_EXTENSION_HERE)$/.
  • scratch-editor/packages/scratch-vm/src/virtual-machine.js
    /**
    * @returns {string} Project in a Scratch 3.0 JSON representation.
    */
    saveProjectSb3 () {
    const soundDescs = serializeSounds(this.runtime);
    const costumeDescs = serializeCostumes(this.runtime);
    const projectJson = this.toJSON();

    // TODO want to eventually move zip creation out of here, and perhaps
    // into scratch-storage
    const zip = new JSZip();

    // Put everything in a zip file
    zip.file('project.json', projectJson);
    this._addFileDescsToZip(soundDescs.concat(costumeDescs), zip);

    return zip.generateAsync({
    type: 'blob',
    mimeType: 'application/x.scratch.sb3',
    compression: 'DEFLATE',
    compressionOptions: {
    level: 6 // Tradeoff between best speed (1) and best compression (9)
    }
    });
    }
    This is not directly related to the project extension, but you should adjust it still. You should keep the start of the MIME type the same (application/x.).

Changing the sprite file extension

There are a few places you need to change to adjust the sprite file extension.

  • scratch-editor/packages/scratch-gui/src/components/sprite-selector/sprite-selector.jsx
    <ActionMenu
    className={styles.addButton}
    img={spriteIcon}
    moreButtons={[
    {
    title: intl.formatMessage(messages.addSpriteFromFile),
    img: fileUploadIcon,
    onClick: onFileUploadClick,
    fileAccept: '.svg, .png, .bmp, .jpg, .jpeg, .sprite2, .sprite3, .gif',
    fileChange: onSpriteUpload,
    fileInput: spriteFileInput,
    fileMultiple: true
    }, {
    title: intl.formatMessage(messages.addSpriteFromSurprise),
    img: surpriseIcon,
    onClick: onSurpriseSpriteClick // TODO need real function for this
    }, {
    title: intl.formatMessage(messages.addSpriteFromPaint),
    img: paintIcon,
    onClick: onPaintSpriteClick // TODO need real function for this
    }, {
    title: intl.formatMessage(messages.addSpriteFromLibrary),
    img: searchIcon,
    onClick: onNewSpriteClick
    }
    ]}
    title={intl.formatMessage(messages.addSpriteFromLibrary)}
    tooltipPlace={isRtl(intl.locale) ? 'right' : 'left'}
    onClick={onNewSpriteClick}
    />
    Add your sprite file extension to fileAccept.
  • scratch-editor/packages/scratch-gui/src/containers/target-pane.jsx
    handleExportSprite (id) {
    const spriteName = this.props.vm.runtime.getTargetById(id).getName();
    const saveLink = document.createElement('a');
    document.body.appendChild(saveLink);

    this.props.vm.exportSprite(id).then(content => {
    downloadBlob(`${spriteName}.sprite3`, content);
    });
    }
    Change sprite3 to your sprite file extension.
  • scratch-editor/packages/scratch-vm/src/virtual-machine.js
    exportSprite (targetId, optZipType) {
    const soundDescs = serializeSounds(this.runtime, targetId);
    const costumeDescs = serializeCostumes(this.runtime, targetId);
    const spriteJson = this.toJSON(targetId);

    const zip = new JSZip();
    zip.file('sprite.json', spriteJson);
    this._addFileDescsToZip(soundDescs.concat(costumeDescs), zip);

    return zip.generateAsync({
    type: typeof optZipType === 'string' ? optZipType : 'blob',
    mimeType: 'application/x.scratch.sprite3',
    compression: 'DEFLATE',
    compressionOptions: {
    level: 6
    }
    });
    }
    This is not directly related to the sprite extension, but you should adjust it still. You should keep the start of the MIME type the same (application/x.).

Scratch commit hashes at the time of this tutorial
scratch-editor:     810ac12eaa1a1eb19d05fcb37f486ad1c4c56314
scratch-blocks: bb2f7ce297e2552767b531c212b18ee4f046e92d