F# is a cross-platform, open-source functional programming language that runs on the .NET platform. It features strong type inference, pattern matching, and a concise syntax that also supports object-oriented and imperative programming styles.
In LiveCodes, F# (Wasm) runs on the real .NET runtime using a WebAssembly-based F# compiler (the F# compiler service compiled to WebAssembly).
Unlike the F# compiler that compiles to JavaScript using Fable, F# (Wasm) uses the actual F# compiler and .NET runtime. This matches the behavior of the official F# compiler. However, the .NET WebAssembly runtime needs to be downloaded in the result page, which can take some time on the first run.
Usage
Demo:
show code
- JS
- TS
- React
- Vue
- Svelte
- Solid
- Preact
- Web Components
import { createPlayground } from 'livecodes';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
return (<LiveCodes {...options} />);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import LiveCodes from 'livecodes/svelte';
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
</script>
<LiveCodes {...options} />
import LiveCodes from 'livecodes/solid';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
return (<LiveCodes {...options} />);
}
import LiveCodes from 'livecodes/preact';
export default function App() {
const options = {
"config": {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
}
};
return (<LiveCodes {...options} />);
}
<live-codes></live-codes>
<script type="module">
import "livecodes/web-components";
const playground = document.querySelector("live-codes");
playground.config = {
"activeEditor": "script",
"script": {
"language": "fsharp-wasm",
"content": "let rec fibonacci n =\n if n <= 1 then n\n else fibonacci (n - 1) + fibonacci (n - 2)\n\nfor i in 0 .. 10 do\n printfn \"fibonacci %d = %d\" i (fibonacci i)\n"
},
"mode": "simple",
"tools": {
"status": "full"
}
};
</script>
Standard I/O
F# (Wasm) code runs in the context of the result page. Standard output (e.g. printfn) is captured and displayed in the console. Standard input is passed by setting the livecodes.fsharp.input property in JavaScript and is read in the F# code using System.Console.ReadLine().
Communication with JavaScript
A few helper properties and methods are available in the browser global livecodes.fsharp object:
livecodes.fsharp.input: The initial standard input passed to the F# code.
livecodes.fsharp.loaded: A promise that resolves when the F# environment (the .NET WebAssembly runtime) is fully loaded. Other helpers should be used after this promise resolves.
livecodes.fsharp.output: The standard output from the F# code execution.
livecodes.fsharp.error: The error message (if any) from the F# code execution.
livecodes.fsharp.exitCode: The exit code of the F# code execution.
livecodes.fsharp.run: A function that runs the F# code with new input. This function takes a string as input and returns a promise that resolves with an object containing the output, error, and exitCode properties.
Example:
show code
- JS
- TS
- React
- Vue
- Svelte
- Solid
- Preact
- Web Components
import { createPlayground } from 'livecodes';
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
return (<LiveCodes {...options} />);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import LiveCodes from 'livecodes/svelte';
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
</script>
<LiveCodes {...options} />
import LiveCodes from 'livecodes/solid';
export default function App() {
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
return (<LiveCodes {...options} />);
}
import LiveCodes from 'livecodes/preact';
export default function App() {
const options = {
"template": "fsharp-wasm",
"params": {
"activeEditor": "markup"
}
};
return (<LiveCodes {...options} />);
}
<live-codes
template="fsharp-wasm"></live-codes>
<script type="module">
import "livecodes/web-components";
const playground = document.querySelector("live-codes");
playground.params = {
"activeEditor": "markup"
};
</script>
Language Info
Name
fsharp-wasm
Aliases / Extensions
fs, fsx, fsharp, wasm.fs, fs-wasm, wasm.fsx
Editor
script
Compiler
The real F# compiler service running on a .NET WebAssembly runtime.
Version
F# 10.1 (FSharp.Compiler.Service 43.12.400), running on .NET 10.0
Not supported.
Live Reload
By default, new code changes are sent to the result page for re-evaluation without a full page reload. This behavior can be disabled by adding the code comment // __livecodes_reload__ to the F# code, which forces a full page reload.
This comment can be added in the hiddenContent property of the editor for embedded playgrounds.
Starter Template
https://livecodes.io/?template=fsharp-wasm
Links