First of let's make sure we are clear of how an olta project is structured. It's helpful to think of a project as a way of managing a certain peice of media.

overview diagram


A project is a smart contract runnning on polygon blockchian. It manages editions and is where the metadata is stored. Each project is meant for one piece of media, e.g an artwork or a piece of music.


Source code for the project smart contract can be found on githubopen in new window


Each project will have a number of editions accociatated with it. Editions are ERC-721open in new window NFTs, they are unique renders of the same media and will share a lot of metadata.

Editions are minted "on-demand", so technically they don't exist until minted.

Each edition will have a unique number and may contain other propertys such as a seed. The key take away is that these unique properties are added to the url so they can be rendered when viewed in a browser.

By reading the url editions can be made unique aswell as dynamic


The media content of a project is simply a website made up of code and assets. Media is stored permently on arweave and the resulting url is stored in the project metadata.

Media can be uploaded as a zip file via our upload form

We are un-opinioniated when it comes to how the media is made. Use whatever libaries/frameworks you whish to. There are however a few must haves.

Folder Structure

You are free to structure your projects media however you like. Assets and libaries should be included in the zip file.

└── project.zip
    ├── index.html
    ├── app.webmanifest
    ├── main.js
    ├── style.css
    ├── thumbnail.png
    ├── 📁 assets
    |   ├── image.png
    |   ├── 3d-model.glb
    |   └── ...
    └── 📁 lib
        ├── p5.min.js
        └── ...

an example of a zip file

Essentials Files


Must be in the root level of your zip file


Make sure if your importing scripts use module typeopen in new window

<script type="module" src="main.js"></script>

Use Relative Paths

When importing scripts use relative paths.

<script src="lib/p5.min.js"></script>
import { someModule } from './lib/someModules.js';

This is related to how folders are deliviered on the Arweave gateway. Without relative paths your files will not resolve. For in-depth detail see path manifestsopen in new window


A standard for progressive web apps necessary for the project to be downloaded and be presented similarly to a native app. It is also used to auto fill in forms on our website. Currently this is how a thumbnail is uploaded.

  "name": "Project Name",
  "description": "This project is meta as can be",
  "screenshots": [
      "src": "thumbnail.png",
      "sizes": "1280x720",
      "type": "image/jpg",
      "platform": "wide",
      "label": "Project Thumbnail"

Find out more about Web App Manifestsopen in new window


In the future we will use this file to store other metadata that isn't stored on-chain like instructions or display aspect ratio as the standard already exists.

Best Practices

  • Aim for longevity, if possible store everything on arweave by including it in the zip file.
  • If you rely on an off-chain API make sure to make it known in the description and consider if it would be possible to replace if it was to go down or disapear.