AngelMunoz/Perla
50.8
Adequate · 2 October 2026
13.5k
lines of production code
F#
with JavaScript
1
measurement over time
What this system is
Perla is a F\#-based development toolchain and build system designed to streamline the creation and management of modern web applications. It provides a local development server that integrates Fable for F\# to JavaScript compilation with Esbuild, while managing frontend dependencies via JSPM and supporting extensibility through a plugin system. The tool also includes type-safe bindings for JavaScript testing frameworks like Mocha and QUnit, enabling a cohesive workflow for building, testing, and serving F\#-powered web projects.
How it got here
2021 — Project initialization and core build tooling
4 changes.
The project was initialized with a new repository structure, replacing the legacy FSharp.DevServer with a modernized Perla CLI targeting .NET 8 and 10. Core infrastructure was established, including a centralized package management system, a BuildService for Fable and Esbuild integration, and a configuration system for managing development server settings and local database persistence.
2022 — Core infrastructure and sample expansion
7 changes.
This period focused on establishing core tooling infrastructure by introducing the Perla.Logger package for structured console output and the Perla.Plugins system for file transformations. Concurrently, the project expanded its sample applications to demonstrate Fable and Lit integration, including multilingual support and PWA capabilities, while adding comprehensive test suites to validate these new modules.
2023–2025 — Package management and testing infrastructure
5 changes.
This period focused on establishing a robust JSPM-based package management system for handling frontend dependencies, complete with comprehensive unit tests. It also expanded the testing ecosystem by introducing Fable bindings for Mocha and QUnit, while updating offline templates to align with the latest schema and framework versions.
Features
Added Fira Code font support and PWA manifest for the sample app
The sample assets now include a CSS file defining the Fira Code typeface (including variable font support) and a web manifest file that configures the application as a standalone Progressive Web App with portrait orientation and a white background.
sample/assets · high confidence
Introduce Perla build tooling and configuration system
This change introduces the core build and configuration infrastructure for the Perla project. It adds a new BuildService to orchestrate the compilation pipeline, including Fable and Esbuild integration, and manages the generation of the final index.html by injecting JavaScript and CSS entry points along with import maps. A new Configuration system allows users to override development server settings (such as port, host, and live reload) and testing options via command-line arguments. The project also establishes a local database using LiteDB to persist template metadata and setup checks, and defines a set of constants (Constants.fs) that standardize paths, default versions (e.g., Esbuild 0.25.6), and configuration file names across the tool.
src/Perla · high confidence
Introduce Perla.Logger package with structured console output and status spinners
The new Perla.Logger library provides a unified logging interface for the Perla toolchain, leveraging Serilog for backend logging and Spectre.Console for rich, colored terminal output. Users benefit from structured log prefixes (e.g., Build, Serve, Browser) that categorize messages, along with visual status spinners for long-running asynchronous tasks. The logger supports customizable prefixes, optional exception display (with debug-specific details), and controls for line endings and ANSI escaping, ensuring consistent and readable console interactions across the platform.
src/Perla.Logger · high confidence
Introduce Perla.PkgManager for JSPM-based package management
Added the Perla.PkgManager module, which provides the core logic for installing, updating, and uninstalling JavaScript packages via the JSPM API. This new component handles downloading package files to a global cache, creating symlinks within the project's .perla directory, and extracting package metadata from various CDN providers (JSPM, esm.sh, jsDelivr, unpkg). It introduces types for import maps, generator options, and download responses, enabling the application to manage frontend dependencies with support for scoped packages and flat directory structures.
src/Perla.PkgManager · high confidence
Introduce plugin system with file transformation capabilities
The Perla.Plugins library now provides a structured way to define and execute plugins that transform source files. It introduces a \FileTransform\ record that tracks file content, extension, and source path, along with predicates to determine which files a plugin should process. Users can define plugins using a builder syntax that supports synchronous, Task-based, and Async transformations. The \PluginManager\ in the Registry module handles the lifecycle of these plugins, including loading them from code or text, managing FSI evaluation sessions, and executing them in a specified order against input files.
src/Perla.Plugins · high confidence
New Fable bindings for Mocha and QUnit testing frameworks
Added new F\# libraries (Perla.Fable.Mocha and Perla.Fable.QUnit) that provide type-safe bindings for the Mocha and QUnit JavaScript testing frameworks. The Mocha library exposes BDD-style interfaces (describe, it, context) and TDD-style interfaces (suite, test) with support for synchronous and asynchronous tests, hooks (before, after, beforeEach, afterEach), and test modifiers (only, skip). The QUnit library provides bindings for test definitions (test, testOnly, testSkip, testTodo, testIf), module management (module, moduleOnly, moduleSkip, moduleTodo, moduleIf), assertion helpers (Assert type with methods like equal, deepEqual, ok, throws), and an Expect module for fluent assertions.
src/Perla.Fable.Mocha, src/Perla.Fable.QUnit · high confidence
New Perla Dev Server sample app with Fable and Lit integration
A new sample application has been added to demonstrate a minimal Perla setup using Fable for F\# to JavaScript compilation and Lit for web components. The sample includes a configuration file (perla.json) that defines build paths, mounts directories, and specifies dependencies such as Lit and fsharp-components. It also provides an import map (perla.json.importmap) to resolve these dependencies via CDN or local packages, and an HTML entry point that loads the compiled Fable output as an ES module. This sample serves as a reference for users wanting to integrate F\# with modern web component frameworks using Perla's dev server.
sample · high confidence
New sample application with multilingual support and Lit integration
The sample application has been rewritten to demonstrate a Fable/Sutil frontend that integrates with Lit web components. It now features a language selector allowing users to switch between English, German, and Spanish, with translations loaded from a JSON file. The UI includes a notification generator form and displays notifications using custom Lit elements. Additionally, the sample embeds Lit-rendered content into specific DOM nodes and registers a custom web component, showcasing interoperability between the F\# stack and JavaScript-based Lit libraries.
sample/src · high confidence
Project initialization and repository structure setup
The repository has been initialized with the core project structure, including the new \Perla.slnx\ solution file (replacing the legacy \FSharp.DevServer.sln\), \.editorconfig\ for F\# formatting, and \global.json\ targeting .NET SDK 10.0.100. Essential documentation and community files have been added, such as \README.md\, \CONTRIBUTING.md\, \LICENSE\ (MIT), and \CODE\_OF\_CONDUCT.md\. The setup also includes Gitpod support (\.gitpod.yml\, \.gitpod.Dockerfile\), installation scripts for Linux/macOS (\install.sh\) and Windows (\install.ps1\), and JSON schemas for configuration (\perla.schema.json\) and templates (\perla.templates.schema.json\).
(repo-wide) · high confidence
Removals
Removal of FSharp.DevServer project scaffolding
The entire FSharp.DevServer project has been removed from the codebase. This deletion eliminates the previous development server implementation, including its command-line argument parsing (for server port, host, and public directory), build configuration, and server lifecycle management (start, stop, restart) built on Saturn and Giraffe. Users will no longer have access to this specific local development server tooling.
src/FSharp.DevServer · high confidence
Behavioural changes
Updated offline templates to schema version 2025-07 and refreshed framework dependencies
The offline templates (basic, blocal, empty-fable, empty-jsx, fable-feliz) now use the 2025-07 schema version in their perla.json files. The Fable Feliz template has been updated to use React 19.1.0 and react-dom 19.1.0, and the Empty JSX template now uses Preact with esbuild JSX automatic mode. All templates include updated QUnit-based test suites and standardized project structures.
src/Perla/offline-templates · high confidence
Test coverage
Added comprehensive test suites for core Perla modules; Added unit tests for package manager core logic; Added unit tests for the Perla.Plugins library; Initial test suite for translation logic.
Dependencies
Migrate to .NET 8/10 and adopt central package management
The project has been upgraded from .NET 5 to support .NET 8 and .NET 10, with the main Perla CLI targeting both frameworks. A new \Directory.Packages.props\ file introduces central package management, defining specific versions for dependencies such as FSharp.Core (9.0.300), Fable.Core (4.5.0), and Microsoft.Playwright (1.52.0). This change replaces the legacy \FSharp.DevServer\ project and its older dependencies (e.g., Saturn, Argu) with a modernized structure including new packages like \Perla.Logger\ and \Perla.PkgManager\.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 50 → 51 (+1.3)
- Rubric changed (rubric-2026.09.13 → rubric-2026.10.1) — scores are not directly comparable.
Lenses
- Code Health 56 → 57 (+0.8)
- Architecture 93 → 96 (+3.4)
- Maturity 56 → 61 (+5.1)
- Readiness 38 → 38 (-0.0)
- Security 74 → 70 (-3.8)
- Accessibility 58 → 58 (+0.4)
- Performance 100 (new)
Resolved (25)
- Documentation: no installation or build instructions
- Documentation: no project overview
- Documentation: written for insiders
- Duplicated block (11–12 lines × 2) (src/Perla/Json.fs)
- Duplicated block (17–18 lines × 2) (src/Perla/VirtualFileSystem.fs)
- Edited copy of a member (37 corresponding lines) (src/Perla/Esbuild.fsi)
- Edited copy of a member (68 corresponding lines) (src/Perla/PlatformOps.fsi)
- Low coverage: Perla.Logger/Library.fs (Perla.Logger/Library.fs)
- Low coverage: Perla.PkgManager/RequestHandler.fs (Perla.PkgManager/RequestHandler.fs)
- Low coverage: Perla.PkgManager/Types.fs (Perla.PkgManager/Types.fs)
- Low coverage: Perla/Build.fs (Perla/Build.fs)
- Low coverage: Perla/Commands.fs (Perla/Commands.fs)
- Low coverage: Perla/Configuration.fs (Perla/Configuration.fs)
- Low coverage: Perla/Directories.fs (Perla/Directories.fs)
- Low coverage: Perla/Esbuild.fs (Perla/Esbuild.fs)
- Low coverage: Perla/Fable.fs (Perla/Fable.fs)
- Low coverage: Perla/Handlers.fs (Perla/Handlers.fs)
- Low coverage: Perla/Library.fs (Perla/Library.fs)
- Low coverage: Perla/Orchestration.fs (Perla/Orchestration.fs)
- Low coverage: Perla/PlatformOps.fs (Perla/PlatformOps.fs)
- …and 5 more
New (35)
- Duplicated block (11 lines × 2) (src/Perla/Json.fs)
- Duplicated block (17–18 lines × 2) (src/Perla/VirtualFileSystem.fs)
- Edited copy of a member (37 corresponding lines) (src/Perla/Esbuild.fs)
- Edited copy of a member (68 corresponding lines) (src/Perla/PlatformOps.fs)
- End-of-life runtime: .NET net9.0
- GeneratorOptionModule.toDict (cyclomatic 29) (src/Perla.PkgManager/Types.fs)
- Low coverage: src/Perla.Logger/Library.fs (src/Perla.Logger/Library.fs)
- Low coverage: src/Perla.PkgManager/RequestHandler.fs (src/Perla.PkgManager/RequestHandler.fs)
- Low coverage: src/Perla.PkgManager/Types.fs (src/Perla.PkgManager/Types.fs)
- Low coverage: src/Perla/Build.fs (src/Perla/Build.fs)
- Low coverage: src/Perla/Commands.fs (src/Perla/Commands.fs)
- Low coverage: src/Perla/Configuration.fs (src/Perla/Configuration.fs)
- Low coverage: src/Perla/Directories.fs (src/Perla/Directories.fs)
- Low coverage: src/Perla/Esbuild.fs (src/Perla/Esbuild.fs)
- Low coverage: src/Perla/Fable.fs (src/Perla/Fable.fs)
- Low coverage: src/Perla/Handlers.fs (src/Perla/Handlers.fs)
- Low coverage: src/Perla/Library.fs (src/Perla/Library.fs)
- Low coverage: src/Perla/Orchestration.fs (src/Perla/Orchestration.fs)
- Low coverage: src/Perla/PlatformOps.fs (src/Perla/PlatformOps.fs)
- Low coverage: src/Perla/Program.fs (src/Perla/Program.fs)
- …and 15 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
AngelMunoz/Perla was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 2 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 731531bc68407b3c5fa1c9dfb236eeb0ebba73c1 — the exact code this score is about.
- Scored under rubric-2026.10.1 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-351388015767.