Gleam
Gleam is a friendly language for building type-safe systems that scale!
Gleam is a statically-typed functional programming language, which compiles to Erlang or JavaScript.
Usage
LiveCodes compiles Gleam code to JavaScript using the WebAssembly (wasm) version of the official Gleam compiler. The compiled JavaScript code is then executed in the context of the result page.
The compiled JavaScript code can be inspected in the Compiled Code Viewer in the Tools Pane (below the result page). Console output is shown in the integrated console.
Please note that the compiler messages (e.g. errors and warnings) are shown in the browser console (not the integrated console).
Standard Library
Gleam's standard library in addition to the following packages are available for use and can be imported as usual with no additional configuration:
Demo:
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\nimport gleam/string\n\npub fn main() {\n \"hello world!\"\n |> string.uppercase\n |> io.println\n}"
},
"tools": {
"status": "open"
}
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\nimport gleam/string\n\npub fn main() {\n \"hello world!\"\n |> string.uppercase\n |> io.println\n}"
},
"tools": {
"status": "open"
}
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\nimport gleam/string\n\npub fn main() {\n \"hello world!\"\n |> string.uppercase\n |> io.println\n}"
},
"tools": {
"status": "open"
}
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\nimport gleam/string\n\npub fn main() {\n \"hello world!\"\n |> string.uppercase\n |> io.println\n}"
},
"tools": {
"status": "open"
}
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\nimport gleam/string\n\npub fn main() {\n \"hello world!\"\n |> string.uppercase\n |> io.println\n}"
},
"tools": {
"status": "open"
}
}
};
let container;
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Custom Modules
Custom modules can be used in Gleam code. These modules have to be precompiled (to JavaScript) by the Gleam compiler. URLs to the compiled JavaScript code and either the Gleam source code or URLs to the Gleam source code are needed to be able to import custom modules.
This is an example for a repo with precompiled Gleam modules:
https://github.com/live-codes/gleam-precompiled
Please refer to Gleam CLI docs for details about adding and building packages.
Note that the built code was committed to the repo by clearing out .gitignore
file.
The built code can then by accessed from a CDN that mirrors GitHub, like this:
https://cdn.jsdelivr.net/gh/live-codes/gleam-precompiled@main/...
Built modules can then be declared in custom settings (App menu → Custom Settings), under the gleam
property, by adding a modules
property.
The modules
property is an object that has the module name as the key. The value is an object with the following properties:
srcUrl
: the URL to the Gleam source code of the module.src
: optionally use this instead of srcUrl
to specify the Gleam source code of the module.compiledUrl
: the URL to the compiled JavaScript code of the module.
Example:
Custom Settings
{
"gleam": {
"modules": {
"plinth/browser/document": {
"srcUrl": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/build/packages/plinth/src/plinth/browser/document.gleam",
"compiledUrl": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/build/dev/javascript/plinth/plinth/browser/document.mjs"
}
}
}
}
See the demo below (open in LiveCodes).
If compiledUrl
property is not specified, the JavaScript module is imported from this URL pattern: {module_name}.mjs
(example: plinth/browser/document.mjs
).
This can then be mapped (using import maps) in custom settings (App menu → Custom Settings) to the full URL of the compiled JavaScript code.
Example:
Custom Settings
{
"gleam": {
"modules": {
"some_pkg/some_module": {
"srcUrl": "https://example.com/packages/some_pkg/some_module.gleam"
},
"another_pkg/another_module": {
"srcUrl": "https://example.com/packages/another_pkg/another_module.gleam"
}
}
},
"imports": {
"some_pkg/some_module.mjs": "https://example.com/compiled/some_pkg/some_module.mjs",
"another_pkg/": "https://example.com/compiled/another_pkg/"
}
}
Externals
External functions written in JavaScript can also be used. An external function has the @external
attribute on it. It needs to specify a "relative" URL specifying the location of the external code. This URL is mapped (using import maps) in custom settings (App menu → Custom Settings) to the full URL of the script that contains the code.
Example:
The following script is hosted on this URL:
https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js
greet.js
export const hello = (str) => `Hello, ${str}!`;
Use this in custom settings:
Custom Settings
{
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
"my_pkg/greet.js"
can then be used in the @external
attribute.
Gleam
import gleam/io
@external(javascript, "my_pkg/greet.js", "hello")
pub fn hello(str: String) -> String
pub fn main() {
io.println(hello("from JavaScript"))
}
Demo:
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n@external(javascript, \"my_pkg/greet.js\", \"hello\")\npub fn hello(str: String) -> String\n\npub fn main() {\n io.println(hello(\"from JavaScript\"))\n}"
},
"tools": {
"status": "open"
},
"customSettings": {
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n@external(javascript, \"my_pkg/greet.js\", \"hello\")\npub fn hello(str: String) -> String\n\npub fn main() {\n io.println(hello(\"from JavaScript\"))\n}"
},
"tools": {
"status": "open"
},
"customSettings": {
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n@external(javascript, \"my_pkg/greet.js\", \"hello\")\npub fn hello(str: String) -> String\n\npub fn main() {\n io.println(hello(\"from JavaScript\"))\n}"
},
"tools": {
"status": "open"
},
"customSettings": {
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n@external(javascript, \"my_pkg/greet.js\", \"hello\")\npub fn hello(str: String) -> String\n\npub fn main() {\n io.println(hello(\"from JavaScript\"))\n}"
},
"tools": {
"status": "open"
},
"customSettings": {
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n@external(javascript, \"my_pkg/greet.js\", \"hello\")\npub fn hello(str: String) -> String\n\npub fn main() {\n io.println(hello(\"from JavaScript\"))\n}"
},
"tools": {
"status": "open"
},
"customSettings": {
"imports": {
"my_pkg/greet.js": "https://cdn.jsdelivr.net/gh/live-codes/[email protected]/demo/greet.js"
}
}
}
};
let container;
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Data URLs can be used to avoid having to host the external code online. LiveCodes enables creating data URLs easily.
Example:
The import map in the previous example can be rewritten like this:
Custom Settings
{
"imports": {
"my_pkg/greet.js": "data:text/javascript;charset=UTF-8;base64,ZXhwb3J0IGNvbnN0IGhlbGxvID0gKHN0cikgPT4gYEhlbGxvLCAke3N0cn0hYDs="
}
}
NPM Modules
Modules published to npm, deno.land/x and jsr.io can be imported as external functions. There is no need to specify import maps. The package/module name is prefixed with a modifier to specify the source (e.g. npm:uuid
to import the uuid
npm module).
See list of supported CDNs and the respective modifiers in the section about module resolution.
Example:
import gleam/io
@external(javascript, "npm:uuid", "v4")
pub fn uuid() -> String
@external(javascript, "jsr:@kwhinnery/yassify", "yassify")
pub fn yassify(str: String) -> String
pub fn main() {
io.println(uuid())
io.println(yassify("Hello, World!"))
}
Demo:
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n// npm module (https://www.npmjs.com/package/uuid)\n@external(javascript, \"npm:uuid\", \"v4\")\npub fn uuid() -> String\n\n// jsr module (https://jsr.io/@kwhinnery/yassify)\n@external(javascript, \"jsr:@kwhinnery/yassify\", \"yassify\")\npub fn yassify(str: String) -> String\n\npub fn main() {\n io.println(uuid())\n io.println(yassify(\"Hello, World!\"))\n}\n"
},
"tools": {
"status": "open"
}
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n// npm module (https://www.npmjs.com/package/uuid)\n@external(javascript, \"npm:uuid\", \"v4\")\npub fn uuid() -> String\n\n// jsr module (https://jsr.io/@kwhinnery/yassify)\n@external(javascript, \"jsr:@kwhinnery/yassify\", \"yassify\")\npub fn yassify(str: String) -> String\n\npub fn main() {\n io.println(uuid())\n io.println(yassify(\"Hello, World!\"))\n}\n"
},
"tools": {
"status": "open"
}
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n// npm module (https://www.npmjs.com/package/uuid)\n@external(javascript, \"npm:uuid\", \"v4\")\npub fn uuid() -> String\n\n// jsr module (https://jsr.io/@kwhinnery/yassify)\n@external(javascript, \"jsr:@kwhinnery/yassify\", \"yassify\")\npub fn yassify(str: String) -> String\n\npub fn main() {\n io.println(uuid())\n io.println(yassify(\"Hello, World!\"))\n}\n"
},
"tools": {
"status": "open"
}
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n// npm module (https://www.npmjs.com/package/uuid)\n@external(javascript, \"npm:uuid\", \"v4\")\npub fn uuid() -> String\n\n// jsr module (https://jsr.io/@kwhinnery/yassify)\n@external(javascript, \"jsr:@kwhinnery/yassify\", \"yassify\")\npub fn yassify(str: String) -> String\n\npub fn main() {\n io.println(uuid())\n io.println(yassify(\"Hello, World!\"))\n}\n"
},
"tools": {
"status": "open"
}
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "gleam",
"content": "import gleam/io\n\n// npm module (https://www.npmjs.com/package/uuid)\n@external(javascript, \"npm:uuid\", \"v4\")\npub fn uuid() -> String\n\n// jsr module (https://jsr.io/@kwhinnery/yassify)\n@external(javascript, \"jsr:@kwhinnery/yassify\", \"yassify\")\npub fn yassify(str: String) -> String\n\npub fn main() {\n io.println(uuid())\n io.println(yassify(\"Hello, World!\"))\n}\n"
},
"tools": {
"status": "open"
}
}
};
let container;
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Example Usage
This is the Gleam starter template demonstrating the use of standard library, custom modules, external functions and npm modules.
show code
import { createPlayground } from 'livecodes';
const options = {
"template": "gleam"
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"template": "gleam"
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"template": "gleam"
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"template": "gleam"
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
const options = {
"template": "gleam"
};
let container;
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Language Info
Name
gleam
Extension
.gleam
Editor
script
Compiler
The wasm version of the official Gleam compiler.
Version
v1.3.0-rc1
Starter Template
https://livecodes.io/?template=gleam
Links