Skip to content

cbuntingde/woovy-framework

Repository files navigation

Woovy Framework

NPM Version License: MIT Stars

Personal Project Notice: This is a personal, experimental project and has not yet been fully tested for production use. The implementation is a learning exercise and proof-of-concept. Use at your own risk.

Overview

Woovy Framework is a modern, React-based static site generator (SSG) designed for performance, flexibility, and developer experience. Inspired by Gatsby and Next.js, it provides a powerful GraphQL data layer, extensible plugin architecture, and build-time optimizations for generating lightning-fast static websites.

What is Woovy Framework?

Woovy Framework is a comprehensive static site generator that:

  • Generates optimized static HTML at build time for maximum performance
  • Leverages React 18+ with modern hooks and concurrent features
  • Provides a unified GraphQL data layer for querying data from multiple sources
  • Features an extensible plugin system with lifecycle hooks for customization
  • Includes Next.js-style features like API routes and ISR (Incremental Static Regeneration)

Why Use Woovy Framework?

Feature Benefit
GraphQL Data Layer Unified interface for querying filesystem, APIs, and databases
Plugin Ecosystem Extend functionality with source, transformer, and utility plugins
Performance First Automatic code splitting, lazy loading, image optimization
Developer Experience Hot module replacement, error boundaries, comprehensive debugging
Modern Architecture Webpack 5, React 18, TypeScript support

Features

Core Architecture

  • Static Site Generator (SSG) - Generates optimized HTML at build time
  • React 18+ - Modern React with hooks and concurrent features
  • GraphQL Data Layer - Unified query interface for all data sources
  • Webpack 5 - Industry-standard bundler with code splitting
  • Plugin System - Extensible lifecycle hooks and APIs

Data Layer

  • Node System - In-memory node store with createNode API
  • GraphQL Integration - Auto-generated schema from data sources
  • Source Plugins - Filesystem, REST API, custom sources
  • Transformer Plugins - JSON, Markdown, YAML transformation

Page System

  • File-based Routing - Automatic route creation from src/pages/
  • Dynamic Pages - Programmatic page generation via API
  • SSR Support - Server-side rendering with hydration
  • Route Prefetching - Instant navigation with preloader

Performance Optimizations

  • Code Splitting - Automatic per-route bundles
  • Lazy Loading - On-demand component loading
  • Image Optimization - WebP, AVIF generation with sharp
  • Incremental Builds - Only rebuild changed files

Quick Start

Installation

# Clone the repository
git clone https://github.com/cbuntingde/woovy-framework.git
cd woovy-framework

# Install dependencies
npm install

# Start development server
npm run develop

Creating a New Project

# Use the create command
npm run create my-site

# Or manually create the structure
mkdir my-site && cd my-site
npm init -y
npm install woovy-framework

Project Structure

woovy-framework/
├── bin/                    # CLI executables
│   ├── cli.js             # Main CLI entry
│   ├── develop.js         # Development server
│   ├── build.js          # Production build
│   ├── serve.js          # Static file server
│   └── create.js         # Project scaffolding
├── src/                   # Source code
│   ├── api/              # API route handling
│   ├── build/            # Build pipeline & optimization
│   ├── components/       # React components
│   ├── dev-server/       # Development server
│   ├── graphql/          # GraphQL data layer
│   ├── node/             # Node system & storage
│   ├── pages/            # Page routing & generation
│   ├── plugins/          # Plugin system & plugins
│   ├── templates/        # Page templates
│   ├── utils/            # Utilities
│   ├── index.js          # Main entry point
│   ├── ssr.js            # SSR handling
│   └── router.js         # Client-side routing
├── public/               # Static assets (generated)
├── cache/                # Build cache
├── docs/                 # Documentation
├── __tests__/            # Test suites
├── types/                # TypeScript definitions
├── woovy-config.js       # Framework configuration
├── woovy-node.js         # Node API extensions
├── woovy-browser.js     # Browser-specific config
├── woovy-ssr.js          # SSR-specific config
├── webpack.config.js    # Webpack configuration
└── package.json          # Dependencies

Configuration

Basic Configuration (woovy-config.js)

module.exports = {
  siteMetadata: {
    title: 'My Woovy Site',
    description: 'A static site built with Woovy Framework',
    author: 'Your Name',
    siteUrl: 'https://example.com',
  },
  plugins: [
    // Add plugins here
  ],
};

Plugin Configuration

module.exports = {
  siteMetadata: {
    title: 'My Blog',
  },
  plugins: [
    {
      resolve: 'woovy-source-filesystem',
      options: {
        path: './content/blog',
        name: 'blog',
      },
    },
    {
      resolve: 'woovy-transformer-markdown',
      options: {
        plugins: [
          {
            resolve: 'woovy-remark-images',
            options: {
              maxWidth: 800,
            },
          },
        ],
      },
    },
  ],
};

Usage Examples

Creating Pages Programmatically

// woovy-node.js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  
  const result = await graphql(`
    query {
      allMarkdownRemark {
        nodes {
          id
          frontmatter {
            slug
          }
        }
      }
    }
  `);
  
  result.data.allMarkdownRemark.nodes.forEach(node => {
    createPage({
      path: `/blog/${node.frontmatter.slug}`,
      component: require.resolve('./src/templates/blog-post.js'),
      context: {
        id: node.id,
      },
    });
  });
};

Custom Source Plugin

// woovy-source-my-api/index.js
exports.sourceNodes = async ({ actions, createNode, createContentDigest }, config) => {
  const { apiUrl, apiKey } = config;
  
  const response = await fetch(`${apiUrl}/posts`, {
    headers: { Authorization: `Bearer ${apiKey}` }
  });
  
  const posts = await response.json();
  
  for (const post of posts) {
    const node = {
      id: `post-${post.id}`,
      parent: null,
      children: [],
      internal: {
        type: 'BlogPost',
        contentDigest: createContentDigest(post),
      },
      ...post,
    };
    
    createNode(node);
  }
};

Custom Transformer Plugin

// woovy-transformer-csv/index.js
const fs = require('fs');
const csv = require('csv-parse');

exports.onCreateNode = async ({ node, actions, createNode, createContentDigest }) => {
  if (node.extension !== 'csv') return;
  
  const content = fs.readFileSync(node.absolutePath, 'utf8');
  
  // Parse CSV and create nodes
  const records = await parseCsv(content);
  
  for (const record of records) {
    const csvNode = {
      id: `csv-${node.id}-${record.id}`,
      parent: node.id,
      children: [],
      internal: {
        type: 'CsvRecord',
        contentDigest: createContentDigest(record),
      },
      ...record,
      _file: node.absolutePath,
    };
    
    createNode(csvNode);
  }
};

API Reference

Lifecycle Hooks

Hook Phase Description
onPreBootstrap Bootstrap Before bootstrap starts
onPostBootstrap Bootstrap After bootstrap completes
sourceNodes Bootstrap Source data into node system
onCreateNode Transform When a node is created
onCreateSchemaCustomization Schema Customize GraphQL schema
onCreateWebpackConfig Build Modify webpack configuration
createPages Pages Create pages programmatically
onCreatePage Pages When a page is created
onPostBuild Build After build completes

Node API

// Create a node
createNode({
  id: 'unique-id',
  parent: null,
  children: [],
  internal: {
    type: 'MyType',
    contentDigest: createContentDigest(data),
  },
  // Custom fields
  field: 'value',
});

// Add field to existing node
createNodeField({
  node,
  fieldName: 'slug',
  fieldValue: 'my-slug',
});

Page API

// Create a page
createPage({
  path: '/about',
  component: require.resolve('./src/templates/about.js'),
  context: {
    id: '123',
  },
});

// Create a redirect
createRedirect({
  fromPath: '/old-page',
  toPath: '/new-page',
  isPermanent: true,
});

Development

Available Scripts

Command Description
npm run develop Start development server
npm run build Build for production
npm run serve Serve production build
npm run create Create new project
npm test Run test suite
npm run lint Run linter
npm run typecheck Run TypeScript checker
npm run security:audit Run security audit

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run with coverage
npm test -- --coverage

Contributing

Contributions are welcome! Please read our contributing guidelines first.

  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

AI Agent Integration

For AI agents working with Woovy Framework, see the AI Installer Guide for comprehensive documentation on architecture, plugin development, and best practices.


Security

For security vulnerabilities, please email cbuntingde@gmail.com directly rather than using the public issue tracker.


License

MIT License - see LICENSE for details.


Acknowledgments


Created by Chris Bunting · cbuntingde@gmail.com

About

A modern, high-performance web framework for building scalable applications

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors