1.1.54 • Published 4 months ago

frontend-hamroun v1.1.54

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

Frontend Hamroun

A lightweight, modern frontend framework with hooks, virtual DOM, and server-side rendering capabilities.

Features

  • 🚀 Fast Virtual DOM implementation
  • 🎯 Hooks-based state management
  • 🌐 Server-side rendering
  • 📱 Router with dynamic routes
  • 🔄 Context API
  • 🛠️ TypeScript support
  • 📦 Small bundle size (~12KB gzipped)
  • ⚡ Code splitting support

Installation

npm install frontend-hamroun
# or
yarn add frontend-hamroun

Quick Start

import { render, useState } from 'frontend-hamroun';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

render(<Counter />, document.getElementById('root'));

Core Features

Hooks

import { useState, useEffect, useMemo, useContext } from 'frontend-hamroun';

// State Management
const [state, setState] = useState(initialState);

// Side Effects
useEffect(() => {
  // Effect code
  return () => {
    // Cleanup code
  };
}, [dependencies]);

// Memoization
const memoizedValue = useMemo(() => computeExpensiveValue(deps), [deps]);

Routing

import { Link, useRouter } from 'frontend-hamroun';

function App() {
  const router = useRouter();
  
  return (
    <div>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </nav>
      {router.pathname === '/' && <Home />}
      {router.pathname === '/about' && <About />}
    </div>
  );
}

Context API

import { createContext, useContext } from 'frontend-hamroun';

const ThemeContext = createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Click me</button>;
}

Server-Side Rendering

Quick Start

// server.ts
import { renderToString } from 'frontend-hamroun';

const html = await renderToString(<App />, {
  title: 'My SSR App',
  description: 'A server-rendered application',
  scripts: ['/client.js'],
  initialState: {
    user: { id: 1, name: 'John' }
  }
});

Complete SSR Setup

  1. Server Setup:
// server.ts
import express from 'express';
import { renderToString } from 'frontend-hamroun';

const app = express();

app.get('*', async (req, res) => {
  try {
    const html = await renderToString(<App />, {
      title: 'My App',
      description: 'Server-rendered app',
      scripts: ['/client.js'],
      styles: ['/styles.css'],
      meta: {
        'og:title': 'My App',
        'theme-color': '#ffffff'
      },
      initialState: {
        url: req.url,
        user: req.user
      },
      bodyAttrs: { class: 'app-root' },
      htmlAttrs: { lang: 'en' }
    });
    
    res.send(html);
  } catch (error) {
    res.status(500).send('Server Error');
  }
});
  1. Client Hydration:
// client.tsx
import { hydrate } from 'frontend-hamroun';

// Type-safe state access
declare global {
  interface Window {
    __INITIAL_STATE__: {
      url: string;
      user?: { id: number; name: string };
    }
  }
}

const { url, user } = window.__INITIAL_STATE__;

hydrate(<App url={url} user={user} />, document.getElementById('root')!);
  1. Template Customization:
// Custom template options
interface TemplateOptions {
  title: string;
  description?: string;
  scripts?: string[];
  styles?: string[];
  meta?: Record<string, string>;
  initialState?: any;
  bodyAttrs?: Record<string, string>;
  htmlAttrs?: Record<string, string>;
}

SSR Features

  • ✨ Full HTML document generation
  • 🔄 Automatic state hydration
  • 🎨 Customizable templates
  • 📱 Meta tags for SEO
  • 🛡️ XSS protection
  • 🚀 Streaming support
  • 📦 Asset optimization
  • 🔍 Error handling

Best Practices

  1. State Management:
// Shared types between server and client
interface AppState {
  url: string;
  user?: UserData;
  settings: AppSettings;
}

// Server
const state: AppState = {
  url: req.url,
  user: await getUser(req),
  settings: await getSettings()
};

// Client
const { url, user, settings } = window.__INITIAL_STATE__ as AppState;
  1. Error Handling:
// Server-side error boundary
try {
  const html = await renderToString(<App />, options);
  res.send(html);
} catch (error) {
  const errorHtml = await renderToString(
    <ErrorPage error={error} />,
    { title: 'Error' }
  );
  res.status(500).send(errorHtml);
}
  1. Performance Optimization:
// Caching
const cached = await cache.get(cacheKey);
if (cached) return cached;

const html = await renderToString(<App />, {
  ...options,
  scripts: [
    { src: '/client.js', async: true, defer: true }
  ]
});

await cache.set(cacheKey, html, '1h');

Basic SSR Setup

// Server-side rendering with customization
const html = await renderToString(<App />, {
  title: 'My App',
  description: 'Server-rendered application',
  scripts: ['/assets/client.js'],
  styles: ['/assets/styles.css'],
  meta: {
    'theme-color': '#ffffff',
    'og:title': 'My App',
    'og:description': 'My awesome app'
  },
  initialState: {
    user: { name: 'John' }
  },
  bodyAttrs: { class: 'dark-mode' },
  htmlAttrs: { lang: 'en', dir: 'ltr' }
});

Express Server Integration

import express from 'express';
import { renderToString } from 'frontend-hamroun';

const app = express();

app.get('*', async (req, res) => {
  const initialState = {
    url: req.url,
    user: req.user // From your auth middleware
  };

  const html = await renderToString(<App />, {
    title: 'My App',
    scripts: ['/client.js'],
    initialState
  });

  res.send(html);
});

Client-Side Hydration

import { hydrate } from 'frontend-hamroun';

// Access the server-provided state
declare global {
  interface Window {
    __INITIAL_STATE__: any;
  }
}

const initialState = window.__INITIAL_STATE__;

hydrate(
  <App initialState={initialState} />, 
  document.getElementById('root')!
);

CLI Tools

Create a new project:

npx create-frontend-app my-app

Performance

  • Initial bundle: 12KB gzipped
  • Dynamic imports for code splitting
  • Automatic batching for state updates
  • Efficient virtual DOM diffing

Security

  • XSS protection
  • Content Security Policy support
  • Type-safe props
  • Secure by default

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Development Tools

  • TypeScript support
  • Hot Module Replacement
  • Developer tools extension
  • Error boundaries
  • Performance monitoring

Advanced Features

Template Customization

interface TemplateOptions {
  title: string;
  description?: string;
  scripts?: string[];
  styles?: string[];
  meta?: Record<string, string>;
  initialState?: any;
  bodyAttrs?: Record<string, string>;
  htmlAttrs?: Record<string, string>;
}

// Usage with custom template
const html = await renderToString(<App />, {
  title: 'Custom Template',
  styles: ['/styles.css'],
  bodyAttrs: { 'data-theme': 'dark' }
});

Error Handling

// Error boundary component
function ErrorBoundary({ children }) {
  const [error, resetError] = useErrorBoundary();

  if (error) {
    return (
      <div role="alert">
        <h2>Something went wrong</h2>
        <pre>{error.message}</pre>
        <button onClick={resetError}>Try again</button>
      </div>
    );
  }

  return children;
}

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see the LICENSE file for details.

Support

Team

  • Hamroun - Lead Developer

Acknowledgments

Special thanks to the open-source community and all contributors.

1.1.49

4 months ago

1.1.48

4 months ago

1.1.52

4 months ago

1.1.51

4 months ago

1.1.50

4 months ago

1.1.54

4 months ago

1.1.53

4 months ago

1.1.47

4 months ago

1.1.41

5 months ago

1.1.45

5 months ago

1.1.44

5 months ago

1.1.43

5 months ago

1.1.42

5 months ago

1.1.46

5 months ago

1.1.34

5 months ago

1.1.33

5 months ago

1.1.32

5 months ago

1.1.38

5 months ago

1.1.37

5 months ago

1.1.36

5 months ago

1.1.35

5 months ago

1.1.39

5 months ago

1.1.40

5 months ago

1.1.29

5 months ago

1.1.28

5 months ago

1.1.30

5 months ago

1.1.31

5 months ago

1.1.23

5 months ago

1.1.27

5 months ago

1.1.26

5 months ago

1.1.25

5 months ago

1.1.24

5 months ago

1.1.12

5 months ago

1.1.11

5 months ago

1.1.10

5 months ago

1.1.16

5 months ago

1.1.15

5 months ago

1.1.14

5 months ago

1.1.13

5 months ago

1.1.19

5 months ago

1.1.18

5 months ago

1.1.17

5 months ago

1.1.22

5 months ago

1.1.21

5 months ago

1.1.20

5 months ago

1.1.9

5 months ago

1.1.8

5 months ago

1.1.7

5 months ago

1.1.6

5 months ago

1.1.5

5 months ago

1.1.4

5 months ago

1.1.3

5 months ago

1.1.2

5 months ago

1.1.1

5 months ago

1.1.0

5 months ago

1.0.8

5 months ago

1.0.7

5 months ago

1.0.6

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago