Home

Awesome

Motoko Playground

A playground for the Internet Computer's native Motoko language.

The Motoko playground allows users to build and deploy Motoko canisters directly in the browser, without downloading SDK, setting up a local dev environment, and without a wallet.

The Motoko playground consists of

We plan on adding many more features to make playground a full-featured web IDE for the Internet Computer. See our issues for more details. Community contributions are highly welcomed!

Running Locally

Prerequisites:

To run the Motoko Playground locally, proceed as follows after cloning the respository:

npm install # Install `npm` dependencies
npm start # Run the local development server

Deploy the Motoko Playground to your local replica using the following command:

dfx deploy

If you want to deploy frontend, remember to upload assetstorage.wasm.gz to the backend canister and update the module hash in FrontendDeployModal.

npm audit warnings

Vulnerabilities from dev dependencies are false positives, we only aim to fix warnings from npm audit --production.

Update Vessel package list

Editor Integrations

The Motoko Playground supports limited cross-origin communication. If you are building a custom smart contract editor or similar application, you can use the following code snippet to open a project in Motoko Playground:

const PLAYGROUND_ORIGIN = 'https://play.motoko.org'
const APP_ID = 'MyEditor'

// Workplace files for a project
const userFiles = {
  'Main.mo': 'actor { public func hello() : async Text { "Hello World" } }'
}

// GitHub package dependencies for a project
const userPackages = [{
  name: 'quicksort',
  repo: 'https://github.com/dfinity/examples.git',
  version: 'master',
  dir: 'motoko/quicksort/src'
}]

// Open the Motoko Playground in a new window
const playground = window.open(`${PLAYGROUND_ORIGIN}?post=${APP_ID}`, 'playground')

// Call repeatedly until loaded (interval ID used for acknowledgement)
const ack = setInterval(() => {
  const request = {
    type: 'workplace',
    acknowledge: ack,
    packages: userPackages,
    actions: [{
      type: 'loadProject',
      payload: {
        files: userFiles
      }
    }],
    deploy: true
  }
  // Concatenate APP_ID and request JSON
  const data = APP_ID + JSON.stringify(request)
  console.log('Request data:', data)
  playground.postMessage(data, PLAYGROUND_ORIGIN)
}, 1000)

// Listen for acknowledgement
const responseListener = ({source, origin, data}) => {
  if(
          typeof data === 'string' &&
          data.startsWith(APP_ID) &&
          source === playground &&
          origin === PLAYGROUND_ORIGIN
  ) {
    console.log('Response data:', data)
    // Parse JSON part of message (prefixed by APP_ID)
    const response = JSON.parse(data.substring(APP_ID.length))
    if(response.acknowledge === ack) {
      clearInterval(ack)
      window.removeEventListener('message', responseListener)
    }
  }
}
window.addEventListener('message', responseListener)

Note: this works for localhostout of the box. If you would like to use this feature in production, please submit a PR adding your application's public URL to src/integrations/allowedOrigins.js.