{"id":15045374,"url":"https://github.com/sandstorm/fusion4j","last_synced_at":"2026-02-11T04:01:47.054Z","repository":{"id":40544738,"uuid":"474971536","full_name":"sandstorm/fusion4j","owner":"sandstorm","description":"Neos Fusion rendering language for the JVM","archived":false,"fork":false,"pushed_at":"2022-05-06T10:24:22.000Z","size":539,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-10-22T19:44:12.721Z","etag":null,"topics":["component-architecture","declarative-language","jvm","neos","neoscms","template-engine"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sandstorm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-28T11:27:49.000Z","updated_at":"2022-05-03T14:31:39.000Z","dependencies_parsed_at":"2022-08-09T22:50:13.454Z","dependency_job_id":null,"html_url":"https://github.com/sandstorm/fusion4j","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/sandstorm/fusion4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandstorm%2Ffusion4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandstorm%2Ffusion4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandstorm%2Ffusion4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandstorm%2Ffusion4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sandstorm","download_url":"https://codeload.github.com/sandstorm/fusion4j/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandstorm%2Ffusion4j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29326815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component-architecture","declarative-language","jvm","neos","neoscms","template-engine"],"created_at":"2024-09-24T20:51:48.147Z","updated_at":"2026-02-11T04:01:47.036Z","avatar_url":"https://github.com/sandstorm.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fusion4j - declarative rendering language for the JVM based on Neos.Fusion\n\nSupports the Neos Fusion syntax/semantic as\ndescribed [in the official Neos Fusion documentation](https://docs.neos.io/cms/manual/rendering/fusion).\n\n- full Fusion language parser with out-of-the-box [AFX](https://github.com/neos/fusion-afx) support\n- Fusion runtime for the JVM usable as standalone, server-side template engine\n- default Fusion objects from Neos.Fusion\n- written in Kotlin\n- functional, library styled API - modules are usable standalone\n- antlr parser grammar for Fusion / AFX\n- runtime and parser fully stateless, immutable and thread-safe\n- runtime evaluation happens lazy everywhere\n- works great with the IntelliJ [Neos-Support Plugin](https://plugins.jetbrains.com/plugin/9362-neos-support) (except jump-to-class)\n- coming soon: Spring boot integration\n- coming soon: a [Monocle-like](https://github.com/sitegeist/Sitegeist.Monocle) Fusion styleguide for presentational components (also serves as Spring boot example / how to use)\n\nCheck out the BDD feature tests for:\n\n- [lang module](/lang/src/test/resources/bdd/features)\n- [runtime module](/runtime/src/test/resources/bdd/features)\n- [default Fusion module](/default-fusion/src/test/resources/bdd/features)\n\n## Spring integration\n\nCurrently, I develop the Spring Boot integration inside the styleguide sub-package before generalizing it.\n\nFeatures:\n- FusionView for Fusion runtime delegation of Spring view rendering\n- Immutable runtime container for PROD mode (loaded once at startup)\n- Reloadable runtime container for local dev mode (with hot-Fusion-code-reloading on file changes)\n- runtime configuration integration via externalized properties\n- CDI integration: custom EEL Helpers and Fusion Object Implementation as Spring beans\n- Fusion object for HTTP Response\n\nThis is currently WIP, so there is no doc for now :/ but check out: \n- an [example application.yml](/styleguide/src/main/resources/application.yml)\n- an [example controller](/styleguide/src/main/kotlin/io/neos/fusion4j/styleguide/ui/fusionModel/FusionModelPageController.kt)\n- example [Fusion code](/styleguide/src/main/fusion/fusion4j-styleguide) with its \n  corresponding [package loader](/styleguide/src/main/kotlin/io/neos/fusion4j/styleguide/ui/StyleguideFusionPackage.kt)\n\nTODO how to use doc\n\n## fusion4j styleguide\n\nThe styleguide has three purposes:\n- living styleguide for your Fusion components, as known from [Monocle](https://github.com/sitegeist/Sitegeist.Monocle)\n- analyzing / browsing of your parsed and semantically normalized Fusion code\n- real-world example of the Spring integration and fusion4j in action\n\nThe styleguide UI itself is written in fusion4j plus a bit of kotlin models and controllers.\n\nTODO doc\n\n## Info on development state\n\nI consider the current development state *early alpha*. Expect some missing edge-case features, \nbugs and performance issues. Pls report, I need input ;)\n\nThe basic functionality of the Fusion runtime is mainly done. The parser already supports all Fusion syntax features.\nThe lang module contains most logic to implement the Fusion semantics. Only a small part is actually implemented in the\nruntime itself.\n\nMissing features that I'm aware of:\n\n- Bugfix: PositionalArraySorter -\u003e keep track of declared key order instead of alphanumeric key sorting!\n- `@position` sorting in some places: (inside `@context`, `@if`) - WIP\n- Neos.Fusion:Augmenter basic Fusion Object\n- include ant paths, for now just `*` (same folder) and `**` (include all sub-folders) works\n- caching\n- configurable processing of AFX HTML comments / style tags / script tags -\u003e parsing already done\n\nI actively develop this package, feel free to contact me and/or contribute ;)\n\nThings to validate/finish:\n\n- multiline EEL expression tests / error message with offending symbol\n\n## Use-Cases\n\n- use the Neos Fusion declarative rendering approach as standalone template engine in your JVM application!\n    - structured \u0026 testable rendering components\n    - no more messy template includes ;)\n- write awesome code analysis based tools for the Fusion language, e.g.\n    - linters and validators\n    - performance/complexity analysis tools\n    - pre-compilers\n    - documentation tools\n- re-using rendering logic / template integration in a two-stack CMS approach\n    - with Neos as CMS content editing stack (providing both data and template), and\n    - JVM based applications as delivery stack\n    - \"single source of template\"\n\n### two stack CMS with Neos\n\nThere are several reasons for architectures, where the PHP / Neos CMS is *not* front-facing but used as an internal\ncontent editing tool. Content is instead delivered by more \"enterprisy\" technology like JVM web server frameworks (f.e.\nSpring Boot). An architecture approach to separate those concerns is sometimes called \"two-stack CMS\". One stack\nprovides an editing platform\n(Neos CMS) and the other stack delivers a somehow statically released content snapshot. Those two stacks may run in\nseparate networks, where the delivery stack focuses on security, reliability, performance and scalability. The editing\nstack may not have such high availability requirements but focuses more on the editing experience. That's probably why\nyou chose Neos in the first place ;) \u003c3\n\nTODO write concept on how to share templates between two-stacks\n\n## Usage\n\n### include via Maven / Gradle\n\nInternal module dependencies:\n- lang (independent)\n- runtime (lang)\n- default-fusion (lang, runtime)\n- test-utils (lang, runtime)\n\n*For now, there are just SNAPSHOT releases I made local for testing:*\nFirst `0.9.0` release is coming soon...\n\n```kotlin\nrepositories {\n    maven(\"https://s01.oss.sonatype.org/content/repositories/snapshots\")\n    // ...\n}\n\ndependencies {\n    // ...\n    implementation(module(\"io.neos.fusion4j:default-fusion:0.9.0-SNAPSHOT\"))\n    // ...\n    testImplementation(module(\"io.neos.fusion4j:test-utils:0.9.0-SNAPSHOT\"))\n    // ...\n}\n```\n\n### code examples\n\nTODO - I will complete this when the API is more stable.\nFor now, checkout the BDD Steps\n\n- [parser usage](/test-utils/src/main/kotlin/io/neos/fusion4j/test/bdd/steps/FusionParserSteps.kt)\n- [runtime usage](/test-utils/src/main/kotlin/io/neos/fusion4j/test/bdd/steps/FusionRuntimeSteps.kt)\n\nor the Spring integration\n\n- [runtime factory](/styleguide/src/main/kotlin/io/neos/fusion4j/spring/FusionRuntimeFactory.kt)\n\n## Modules\n\nAll parts of fusion4j are designed to give you the experience of *using a library* instead of being caged in a\nframework. There is some code to be written to get started with fusion4j (see usage), but you can use the single aspects\nof this library pretty easily in a standalone way. F.e. you can only parse Fusion code and perform custom logic like\nanalysing it.\n\nNote, that if you want to reuse the BDD step definitions, they are found\n\n### Language module\n\nThis is implemented in the `lang` sub-package.\n\n- grammar definition of Fusion in antlr4\n- validated, consistent and immutable domain model\n    - raw language meta model\n        - parsing of Fusion code into a usable raw AST-like, but Fusion-domain-specific model\n        - AST code references\n        - code comments are part of the raw meta-model!\n        - code comments to fusion element correlation (e.g. for code analysis or a \"Fusion-Doc\")\n    - semantic meta-model / normalization of loaded Fusion files\n        - merging of prototype declarations\n        - merging of path configurations\n        - nested path normalization\n        - application of path erasures\n        - file includes / load order\n        - loading of Fusion object instances\n- DSL support\n    - domain specific language parser API\n    - default DSLs:\n        - AFX\n- Fusion file abstraction\n    - filesystem\n    - classpath\n    - in-memory (String)\n- Reloading Fusion code at runtime is possible by creating a new instance of the Runtime (it's immutable)\n\n### Runtime module (WIP)\n\nThis is implemented in the `runtime` sub-package.\n\n- FusionRuntime implemented for usage in Java\n- immutable, thread-safe Runtime\n- almost everything is evaluated *lazy*\n- TODO/DISCUSS: reactive implementation for reactor / kotlin coroutines\n- IMPORTANT: for now, the runtime is blocking code. If you use Spring Webflux or any other reactive / non-blocking\n  technology, you should load your model first, then use the Fusion Runtime as blocking mapper. -\u003e for now there is no\n  way to use non-blocking code in Fusion Object implementations or EEL Helpers!\n\nImportant classes (also entry points for class documentation):\n\n- FusionRuntimeImplementationAccess\n- FusionRuntime\n\n### Default Fusion module (WIP)\n\nBasic Fusion library - prototypes + implementations of Neos.Fusion\n\nImplemented Fusion prototypes:\n- Neos.Fusion:Join\n- Neos.Fusion:DataStructure\n- Neos.Fusion:Case\n- Neos.Fusion:Matcher\n- Neos.Fusion:Renderer\n- Neos.Fusion:Value\n- Neos.Fusion:Component\n- Neos.Fusion:CanRender\n- Neos.Fusion:Tag\n- Neos.Fusion:Map\n- Neos.Fusion:Loop\n- Neos.Fusion:Reduce\n- Neos.Fusion:Augmenter\n\nDeprecated Fusion objects (will throw an exception on usage with alternative message):\n- Neos.Fusion:Array\n- Neos.Fusion:RawArray\n- Neos.Fusion:Template\n- Neos.Fusion:Collection\n- Neos.Fusion:RawCollection\n- Neos.Fusion:Attributes\n\nUnsupported Fusion objects (will throw an exception on usage with explanation message):\n- Neos.Fusion:Http.ResponseHead\n- Neos.Fusion:Http.Message\n- Neos.Fusion:UriBuilder\n- Neos.Fusion:ResourceUri\n- Neos.Fusion:Link.Resource\n\n## development\n\ngenerate antlr code with:\n`gradlew clean generateGrammarSource`\n\nrun all tests\n`gradlew clean test`\n\nrun styleguide css resources sass compiler\n```\ncd styleguide\nnpm run sass-dev\n```\n\n## further ideas\n\n- (TODO) code analysis API\n    - possible use cases: validators / linters, performance analysis, documentation\n    - API for analysing fusion code on both:\n        - raw lang model\n        - normalized meta model\n    - (TODO / Discuss / Ideas welcome) default analysis for:\n        - unused/unreachable code\n        - raw to normalized \"declaration application path\" debugging (a.k.a. \"which code overrides my root path\"?)\n        - recognition of possible runtime errors / pre-compile-like validations on normalized model, e.g.\n            - type checks, e.g.\n                - warnings on type morphing\n                - render evaluation result type check ()\n            - no implementation class set for prototypes\n        - side effect detection (a.k.a. \"is my component side effect free\"?), looks for:\n            - context mutations via @context meta property\n            - global state access via expression analysis\n\ndiscuss: will there be a reactive/non-blocking IO implementation? do we need one? For now, if you want to use fusion4j\nwith reactor/Spring Boot Webflux or another non-blocking IO library, the rendering logic (more specific: the Fusion\nobject implementations or EEL helper calls) should not perform any blocking IO code. To work around this, perform all\nIO operations before hands (in the controller) and put the emitted object in the Fusion context before rendering.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandstorm%2Ffusion4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandstorm%2Ffusion4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandstorm%2Ffusion4j/lists"}