Skip to content

Installation

Partas.Solid has two NuGet packages:

  • Partas.Solid, the DSL and the bindings.
  • Partas.Solid.FablePlugin, the Fable compiler plugin that turns your F# into JSX. Partas.Solid depends on it.

Fable writes .jsx files, and a bundler such as Vite runs the Solid JSX compiler over them, so you need both a .NET and a Node toolchain.

Requirements

ToolVersion
.NET SDK10 recommended. Partas.Solid targets net8.0, but it references FSharp.Core 10
Fable5.x. The repository pins the tool at 5.13.0
Fable.Core5.2.0, a dependency of Partas.Solid
Node22.12 or later

The .NET side

1. Install Fable

dotnet new tool-manifest
dotnet tool install fable --version 5.13.0

2. Build the 3.0 packages

Clone the repository, check out the Solid 2 branch, and pack both packages into a folder:

git clone https://github.com/shayanhabibi/Partas.Solid.git
cd Partas.Solid
git checkout solid2rc
dotnet pack Partas.Solid.FablePlugin/Partas.Solid.FablePlugin.fsproj -c Release -o ../partas-feed
dotnet pack Partas.Solid/Partas.Solid.fsproj -c Release -o ../partas-feed

3. Add the local feed

Add a nuget.config next to your solution:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="partas-local" value="../partas-feed" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

4. Reference Partas.Solid

dotnet add package Partas.Solid --version 3.0.0

If you use Paket, add nuget Partas.Solid 3.0.0 to paket.dependencies along with a source line for the feed folder, then run paket install.

Partas.Solid brings in Partas.Solid.FablePlugin, Fable.Core 5.2.0, Fable.Browser.Dom 2.20.0, Xantham.Fable.Core.TS and FSharp.Core 10.

The npm side

Solid 2 is a release candidate, so pin the exact versions Partas.Solid 3.0 is tested against:

npm install solid-js@2.0.0-rc.9 @solidjs/web@2.0.0-rc.9
npm install --save-dev vite@8.3.1 @solidjs/vite-plugin@3.0.0-next.44 @solidjs/compiler@2.0.0-rc.9 @solidjs/babel-plugin@2.0.0-rc.9

Or in package.json:

{
  "type": "module",
  "dependencies": {
    "@solidjs/web": "2.0.0-rc.9",
    "solid-js": "2.0.0-rc.9"
  },
  "devDependencies": {
    "@solidjs/babel-plugin": "2.0.0-rc.9",
    "@solidjs/compiler": "2.0.0-rc.9",
    "@solidjs/vite-plugin": "3.0.0-next.44",
    "vite": "8.3.1"
  },
  "overrides": {
    "@solidjs/compiler": "2.0.0-rc.9",
    "@solidjs/babel-plugin": "2.0.0-rc.9",
    "solid-js": "2.0.0-rc.9",
    "@solidjs/web": "2.0.0-rc.9"
  }
}

The overrides block stops npm from pulling in a second, different Solid release (of solid-js, @solidjs/web or the compiler) through the Vite plugin.

In Solid 2 the web runtime moved from solid-js/web to @solidjs/web, which provides render, hydrate, Portal and Dynamic. In F# they are in the Partas.Solid.Web namespace.

A minimal vite.config.js that picks up Fable's output:

import { defineConfig } from "vite";
import solid from "@solidjs/vite-plugin";

export default defineConfig({
  plugins: [
    solid({
      include: ["**/*.jsx"],
      exclude: ["node_modules/**", "**/fable_modules/**"]
    })
  ]
});

Mounting the app

Mount the root component with render. It returns a function that disposes the app.

module App

open Partas.Solid
open Partas.Solid.Web
open Browser.Dom

[<SolidComponent>]
let App () =
    h1 () { "Hello from F#" }

render ((fun () -> App ()), document.getElementById "root") |> ignore

Bindings and Femto

Some binding packages carry npm metadata for Femto, which can then install their npm dependencies for you. Bindings that target Solid 1.x will not work with Solid 2. See the ecosystem for what has been ported.

Compiling

Pass these flags to Fable:

dotnet fable -e .fs.jsx -c Release [--typedArrays false]
FlagWhy
-e .fs.jsxThe plugin emits JSX, so Fable must write files with a .jsx extension. The Solid compiler then reads them.
-c ReleaseF# and Fable produce a different AST in Debug and Release. The plugin was built against the Release AST. Pass -c Release every time, including under dotnet fable watch, which otherwise compiles in Debug.
--typedArrays falseFable compiles numeric arrays to typed arrays, so an int[] becomes an Int32Array. Some libraries expect a plain array and break on typed arrays. Turn them off with this flag, or box the values ([\| box 5 \|]) where it matters.

Next

Edit this page