We have released a new DFX feature that I personally am very excited for: support for large files in asset canisters powered by HTTP requests! For a technical rundown of how we've architected this, check out this Medium post: https://medium.com/@hansl/24e8cbc14a0a.

TLDR - we have released a preview build of a new minor version of DFX, 0.7.0-beta.2, that will upgrade our current asset canister model to one that allows you to serve arbitrary static assets, and removes the 2MB limit.

If you have been currently building UI's on the Internet Computer, there are any number of limitations you may have encountered. Maybe you wanted to deliver your own index.html. You tried to serve static images, or split JavaScript output into multiple files. Our frontend engineers were right there with you. While we are proud of the approach we were able to deliver through our web bootstrap model to get you up and running as soon as possible, we believe that our new approach will get out of your way to build and deliver truly decentralized web experiences.

Try it out yourself

You can download our latest beta DFX version by running this command:

DFX_VERSION=0.7.0-beta.2 sh -ci "$(curl -fsSL <https://sdk.dfinity.org/install.sh>)"

After installing, you will be up and running with this new feature, which will give you time to experiment with the new approach or to update your existing projects before we promote 0.7.0 to latest. If you need to stay on a prior version in the meantime, you can lock a project to a specific DFX version by setting "dfx": "0.6.26" in dfx.json.

On the new beta, running dfx new will give you a slightly different setup than before. We have replaced the ic:canister syntax with relative paths in our generated JavaScript in order to support your ability to bring your own bundler. We are also generating Typescript declarations from the candid to give you additional flexibility and improved tooling.

As a result of deprecating the bootstrap server, we are no longer providing you with window.ic or a default anonymous agent in projects generated via dfx new. The new [canister_name]_assets/src/index.js file in a new project demonstrates our new pattern by setting you up with the following code:

import { Actor, HttpAgent } from "@dfinity/agent";
import {
  idlFactory as [canister_name]_idl,
  canisterId as [canister_name]_id,
} from "dfx-generated/[canister_name]";

const agent = new HttpAgent();
const [canister_name] = Actor.createActor([canister_name]_idl, {
  agent,
  canisterId: [canister_name]_id,
});

document.getElementById("clickMeBtn").addEventListener("click", async () => {
  const name = document.getElementById("name").value.toString();
  const greeting = await [canister_name].greet(name);

  document.getElementById("greeting").innerText = greeting;
});

Here, we initialize an HttpAgent and pass it to our Actor.createActor constructor. We are also importing from an aliased route, "dfx-generated/[canister_name" . The code in that package is generated from the Candid declarations from your canister, and enables us to give you a pleasant, custom interface for your application. We pass that idlFactory along with the HttpAgent, and that returns the actor that you can call using [canister_name].greet in a simple, promise-based syntax.

We hope you'll also be as excited as we are to see an index.html file you are now free to customize. In that file, you can see we are now using traditional relative imports for your image src attribute and linking to main.css.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>test_dfx</title>
    <base href="/">

    <link type="text/css" rel="stylesheet" href="main.css" />
</head>
<body>
    <img src="logo.png" alt="DFINITY logo" />
    <section>
        <label for="name">Enter your name: &nbsp;</label>
        <input id="name" alt="Name" type="text" />
        <button id="clickMeBtn">Click Me!</button>
    </section>
    <section id="greeting"></section>
</body>
</html>

This feature was requested by our own internal developers after struggling with the limits that we currently faced delivering high-quality web experiences with the alpha asset canisters. Going forward, we will be focusing more attention on our npm packages and JavaScript developer experience.

That's where I have a personal announcement! I will be taking ownership of our package monorepo, and will be working full time on improving the developer experience. Please continue to share your honest feedback with us, and I look forward to supporting the JS/TS community developing on the IC. I'll share out a roadmap of planned features soon, but for the immediate term, my priority is to improve documentation and get it into your hands ASAP.

Cheers,