Game-Changing Feature

TypeScript Without Build Steps

Run .ts files directly in the browser. No compilation, no bundling, no setupβ€”just pure TypeScript with instant type stripping.

Instant Type Stripping
Zero Configuration
Blazing Fast

πŸš€ Why This Is Revolutionary

FyneJS is the first reactive framework that lets you run TypeScript component files directly in the browser without any compilation or bundling step.

While other frameworks require complex build setups (Webpack, Vite, Rollup, tsc, etc.) and watch processes to use TypeScript, FyneJS strips types instantly in the browserβ€”as fast as the browser can parse JavaScript.

❌ Traditional Approach

  • β€’ Install TypeScript compiler
  • β€’ Configure tsconfig.json
  • β€’ Set up build tool (Webpack/Vite)
  • β€’ Watch mode for development
  • β€’ Wait for compilation on each change
  • β€’ Deal with source maps

βœ… FyneJS Approach

  • β€’ Write .ts files
  • β€’ Load with FyneJS.loadComponents()
  • β€’ That's it!
  • β€’ Types stripped instantly
  • β€’ Reload page to see changes
  • β€’ No build step ever

How It Works

FyneJS uses a high-performance token-based scanner that strips TypeScript types while preserving runtime behavior and code structure.

1 Write TypeScript Components

Create your component files with full TypeScript supportβ€”interfaces, types, generics, everything.

// components/user-card.ts
import { XTool, html } from 'fynejs';

interface User {
  name: string;
  email: string;
  role: 'admin' | 'user';
}

XTool.registerComponent({
  name: 'user-card',
  template: html`
    <div class="card">
      <h2 x-text="user.name"></h2>
      <p x-text="user.email"></p>
      <span x-text="user.role"></span>
    </div>
  `,
  data: {
    user: { name: 'John', email: 'john@example.com', role: 'admin' } as User
  }
});

2 Load with FyneJS

Use loadComponents() to load your .ts files. FyneJS automatically detects the TypeScript extension and strips types on the fly.

// In your main HTML or setup file
XTool.loadComponents([
  { path: 'components/user-card.ts', mode: 'preload' },
  { path: 'components/dashboard.ts', mode: 'defer' },
  { path: 'components/modal.ts', mode: 'lazy' }
]);

// Or load a single component dynamically
await XTool.loadComponent('components/user-card.ts');

3 Instant Execution

Types are stripped using a single-pass tokenizer with linked token tracking for context awareness. The JavaScript is executed immediatelyβ€”no compilation, no waiting, no build process.

<!-- Use the component immediately -->
<component source="user-card"></component>

<!-- Dynamic loading example -->
<component x:source="'user-card'"></component>

Complete Setup Guide

Follow this pattern for organizing your multi-page FyneJS projects with TypeScript.

Step 1: Create Setup File

Create a central demo-loader.js or app-setup.js file that initializes FyneJS, loads all components, and handles routing.

// demo-loader.js or app-setup.js
(function() {
  // List of component files (mix .ts and .js)
  const componentFiles = [
    'interactive-showcase.ts',  // TypeScript component
    'user-dashboard.ts',         // TypeScript component
    'data-chart.ts',            // TypeScript component
    'shopping-cart.js',         // JavaScript component
    'modal.js'                  // JavaScript component
  ];
  
  const basePath = 'components/';
  
  // Initialize FyneJS
  XTool.init({
    container: 'body',
    debug: false,
    router: {
      enabled: true,
      before: (to, from, info) => {
        console.log(`Navigating from ${from} to ${to}`);
        return true; // Allow navigation
      },
      after: (to, from, info) => {
        console.log(`Navigated to: ${to}`);
      }
    }
  });
  
  // Load all components
  XTool.loadComponents(
    componentFiles.map(file => ({
      path: basePath + file,
      mode: 'preload'  // or 'defer' or 'lazy'
    }))
  );
  
  // Optional: Add code block enhancement
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('pre > code').forEach(block => {
      // Add line numbers, syntax highlighting, etc.
    });
  });
})();

Step 2: Include in HTML Pages

Every HTML page that uses FyneJS should include the framework script and your setup file.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>My FyneJS App</title>
  
  <!-- Styles -->
  <link rel="stylesheet" href="./styles.css" />
  
  <!-- FyneJS Framework -->
  <script src="../dist/x-tool.min.js" defer></script>
  
  <!-- Shared Components -->
  <script src="./shared/navigation.js" defer></script>
  <script src="./shared/footer.js" defer></script>
  
  <!-- Your Setup File (loads TypeScript components) -->
  <script src="./demo-loader.js" defer></script>
</head>
<body>
  <!-- Navigation component -->
  <component source="docs-nav" x-prop="{ page: 'home' }"></component>
  
  <!-- Page content -->
  <main>
    <!-- TypeScript component loaded automatically -->
    <component source="interactive-showcase"></component>
  </main>
  
  <!-- Footer component -->
  <component source="docs-footer"></component>
</body>
</html>

Step 3: Organize Components

Structure your components logically. Mix TypeScript and JavaScript files as needed.

Recommended Structure:

project/
β”œβ”€β”€ index.html
β”œβ”€β”€ about.html
β”œβ”€β”€ contact.html
β”œβ”€β”€ demo-loader.js          # Central setup
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ page-specific/
β”‚   β”‚   β”œβ”€β”€ hero-section.ts      # TypeScript
β”‚   β”‚   β”œβ”€β”€ pricing-table.ts     # TypeScript
β”‚   β”‚   └── testimonials.js      # JavaScript
β”‚   β”œβ”€β”€ features/
β”‚   β”‚   β”œβ”€β”€ user-dashboard.ts
β”‚   β”‚   β”œβ”€β”€ analytics-widget.ts
β”‚   β”‚   └── notification-center.ts
β”‚   └── ui/
β”‚       β”œβ”€β”€ modal.js
β”‚       β”œβ”€β”€ tooltip.js
β”‚       └── dropdown.ts
└── shared/
    β”œβ”€β”€ navigation.js        # Shared across all pages
    └── footer.js           # Shared across all pages

⚑ Performance

Single-pass tokenization with optimized character testing delivers exceptional performance.

~34ms
Blazingly Fast: 983-line TypeScript Component
Real-world performance with the interactive-showcase.ts component

Benchmark Details:

  • β€’ File: 983 lines of TypeScript with interfaces, types, and complex generics
  • β€’ Average Time: ~34ms (including file read, tokenization, and stripping)
  • β€’ Implementation: Token-based scanner with linked token tracking
  • β€’ Memory: Efficient string handling with incremental concatenation
  • β€’ Note: Timing varies based on system load, but consistently fast

Performance Note

Type stripping happens once when the component is loaded. After that, the component runs as pure JavaScript with zero overhead. The stripping time includes file I/O and is far faster than traditional compilation workflows that take seconds or minutes.

Usage Considerations

Understanding the type stripping implementation and its characteristics.

Best Suited for Well-Formed Code

The stripper works best with well-formed TypeScript code. It does not perform full TypeScript parsing but focuses on type syntax removal while preserving runtime behavior and code structure.

Handles Most TypeScript Patterns

The implementation handles most common TypeScript patterns reliably and tries to handle very complex type constructs. The simpler the types, the better the results.

What Gets Removed:

  • β€’ Type annotations (variables, parameters, return types)
  • β€’ Interface, namespace, declare, and type alias declarations
  • β€’ Generics in functions and classes
  • β€’ Import/export declarations (including regular ones, not just type-only)
  • β€’ Non-null assertion operators (!)
  • β€’ Access modifiers (public, private, protected)
  • β€’ Function overload signatures
  • β€’ Type assertions ('as' syntax)
  • β€’ Enum declarations
  • β€’ implements clauses in class declarations

No Type Checking or Runtime Type Info

This is not suitable for runtime type information preservationβ€”types are completely removed. No type checking is performed; use an IDE with TypeScript support (VS Code, WebStorm) for type checking during development.

Consider File Size

While the stripper is fast, consider file size when processing large codebases. Browser environments work best with reasonably-sized component files. You decide what's appropriate for your use case.

Framework Comparison

No other reactive framework offers this capability.

Framework TypeScript Support Build Required Browser-Native .ts
FyneJS βœ… ❌ βœ…
Alpine.js ⚠️ βœ… ❌
Vue βœ… βœ… ❌
React βœ… βœ… ❌
Svelte βœ… βœ… ❌

Ready to Try It?

Start writing TypeScript components without any build setup today.