Publish block libraries
Stay organized with collections
Save and categorize content based on your preferences.
Plugins that provide libraries of block definitions are a great way to share
your reusable blocks with the Blockly community. To make your block library as
versatile and useful as possible, we've developed these guidelines.
Guidelines
- Make it easy for users to install all of your blocks, and make it
possible for users to install only certain blocks or pieces of blocks
they choose.
- Make it easy to install everything: You can do this by providing a
function that installs every piece a single block definition requires
(such as mutators, extensions, mixins, fields, etc.). You can also
provide a function that will install all of the blocks offered by your
plugin at once.
- Make it possible to choose specific parts: You should export all of the
pieces of a block definition separately, so that it is possible for a
user to import only the pieces they need in order to create their own
similar custom block.
- Avoid using side effects in your plugin.
- Blocks, fields, extensions, and other pieces shouldn't be installed as a
side effect of loading your plugin. Users should maintain control over
which things are installed and when. This allows users to import the
pieces they need without worrying that pieces they don't will be
installed.
Use the JSON field registry instead of instantiating new fields directly.
Not Recommended - Instantiating a new field directly:
const myCustomBlock = {
init: function() {
this.appendDummyInput()
.appendField(new Blockly.FieldNumber(123), 'NAME');
}
}
Recommended - JSON field registry:
export const myCustomBlock = {
init: function() {
this.appendDummyInput()
.appendField(Blockly.fieldRegistry.fromJson({
name: 'field_number',
value: 123,
}), 'NAME');
}
}
Using the field registry makes it easier for a user to replace the
implementation of the field used in your block without having to change
the block definition.
Don't make assumptions about what the user has already installed.
- If your plugin requires a custom field or another plugin, register those
fields yourself in your provided
install
function.
- Soon, Blockly will provide tools that let you register
already-registered items without error. Until then, you may want to
check what has already been registered before registering an extension,
mutator, mixin, or field yourself.
- Be clear about any prerequisites or dependencies that are required by
your plugin or block definitions.
Consider providing generator functions for each of the blocks you provide.
- Providing generator functions that work out of the box makes it easier
for users to use your blocks without having to understand their
structure and design. If they have to write their own generator
functions, this may lead to redundant work being done by each user.
- JavaScript is the most commonly used language in Blockly, so if you only
pick one language to provide, we recommend JavaScript, unless your blocks
are built for a specific language such as implementing a Python library.
- Consider posting 'help wanted' issues for languages for which you are
unable to implement generator functions, and accept pull requests for
these if a user contributes them.
If you provide an install function for your block, you can accept an
optional generators
parameter. If a user passes a generator instance
that you support, you can automatically install the block-code generator
function and do related work such as adding reserved words:
// Your plugin's install function
export const installMyCustomBlock(generators = {}) {
Blockly.common.defineBlocks({my_custom_block: myCustomBlock});
if (generators.javascript) {
generators.javascript.forBlock['my_custom_block'] = myCustomGeneratorFunction;
generators.javascript.addReservedWords('specialReservedWord');
}
}
// How a user may install your block
import {javascriptGenerator} from 'blockly/javascript';
import {installMyCustomBlock} from 'blockly-cool-blocks-plugin';
// installs the block definition and the javascript block-code generator
installMyCustomBlock({javascript: javascriptGenerator});
Feedback
If you have questions about how to best follow these guidelines in your plugin,
let us know in the forum! We'd love to see your block libraries and provide
feedback on them.
Note that not all first-party plugins that provide block definitions currently
follow these guidelines, but new plugins will and we plan to migrate existing
plugins.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-05-23 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-05-23 UTC."],[[["\u003cp\u003eDesign block libraries to allow users to install all blocks at once or select specific components for custom integrations.\u003c/p\u003e\n"],["\u003cp\u003eAvoid side effects that automatically install blocks upon plugin loading; users should control installation.\u003c/p\u003e\n"],["\u003cp\u003eUtilize the JSON field registry for easier field implementation replacement without modifying block definitions.\u003c/p\u003e\n"],["\u003cp\u003eEnsure clear documentation of prerequisites and avoid assumptions about user installations to prevent conflicts.\u003c/p\u003e\n"],["\u003cp\u003eConsider providing generator functions, especially for JavaScript, to streamline block usage and reduce redundant work.\u003c/p\u003e\n"]]],["Block library plugins should enable users to easily install all or select blocks. Export all block definition pieces separately, avoiding side effects during plugin loading. Utilize the JSON field registry for field creation instead of direct instantiation. Register required custom fields or plugins within the install function, and clearly state dependencies. Providing generator functions, especially for JavaScript, is recommended for user convenience. Consider adding a `generators` parameters to your plugin install function to install generators if they are provided by the user.\n"],null,["# Publish block libraries\n\nPlugins that provide libraries of block definitions are a great way to share\nyour reusable blocks with the Blockly community. To make your block library as\nversatile and useful as possible, we've developed these guidelines.\n\nGuidelines\n----------\n\n- Make it **easy** for users to install all of your blocks, and make it **possible** for users to install only certain blocks or pieces of blocks they choose.\n - Make it easy to install everything: You can do this by providing a function that installs every piece a single block definition requires (such as mutators, extensions, mixins, fields, etc.). You can also provide a function that will install all of the blocks offered by your plugin at once.\n - Make it possible to choose specific parts: You should export all of the pieces of a block definition separately, so that it is possible for a user to import only the pieces they need in order to create their own similar custom block.\n- Avoid using side effects in your plugin.\n - Blocks, fields, extensions, and other pieces shouldn't be installed as a side effect of loading your plugin. Users should maintain control over which things are installed and when. This allows users to import the pieces they need without worrying that pieces they don't will be installed.\n- Use the JSON field registry instead of instantiating new fields directly.\n\n - Not Recommended - Instantiating a new field directly:\n\n const myCustomBlock = {\n init: function() {\n this.appendDummyInput()\n .appendField(new Blockly.FieldNumber(123), 'NAME');\n }\n }\n\n - Recommended - JSON field registry:\n\n export const myCustomBlock = {\n init: function() {\n this.appendDummyInput()\n .appendField(Blockly.fieldRegistry.fromJson({\n name: 'field_number',\n value: 123,\n }), 'NAME');\n }\n }\n\n - Using the field registry makes it easier for a user to replace the\n implementation of the field used in your block without having to change\n the block definition.\n\n- Don't make assumptions about what the user has already installed.\n\n - If your plugin requires a custom field or another plugin, register those fields yourself in your provided `install` function.\n - Soon, Blockly will provide tools that let you register already-registered items without error. Until then, you may want to check what has already been registered before registering an extension, mutator, mixin, or field yourself.\n - Be clear about any prerequisites or dependencies that are required by your plugin or block definitions.\n- Consider providing generator functions for each of the blocks you provide.\n\n - Providing generator functions that work out of the box makes it easier for users to use your blocks without having to understand their structure and design. If they have to write their own generator functions, this may lead to redundant work being done by each user.\n - JavaScript is the most commonly used language in Blockly, so if you only pick one language to provide, we recommend JavaScript, unless your blocks are built for a specific language such as implementing a Python library.\n - Consider posting 'help wanted' issues for languages for which you are unable to implement generator functions, and accept pull requests for these if a user contributes them.\n - If you provide an install function for your block, you can accept an\n optional `generators` parameter. If a user passes a generator instance\n that you support, you can automatically install the block-code generator\n function and do related work such as adding reserved words:\n\n // Your plugin's install function\n export const installMyCustomBlock(generators = {}) {\n Blockly.common.defineBlocks({my_custom_block: myCustomBlock});\n if (generators.javascript) {\n generators.javascript.forBlock['my_custom_block'] = myCustomGeneratorFunction;\n generators.javascript.addReservedWords('specialReservedWord');\n }\n }\n\n // How a user may install your block\n import {javascriptGenerator} from 'blockly/javascript';\n import {installMyCustomBlock} from 'blockly-cool-blocks-plugin';\n // installs the block definition and the javascript block-code generator\n installMyCustomBlock({javascript: javascriptGenerator});\n\nFeedback\n--------\n\nIf you have questions about how to best follow these guidelines in your plugin,\nlet us know in the forum! We'd love to see your block libraries and provide\nfeedback on them.\n\nNote that not all first-party plugins that provide block definitions currently\nfollow these guidelines, but new plugins will and we plan to migrate existing\nplugins."]]