{"id":31825756,"url":"https://github.com/sidmaz666/peachy","last_synced_at":"2025-10-11T16:24:29.692Z","repository":{"id":284382522,"uuid":"954763037","full_name":"Sidmaz666/peachy","owner":"Sidmaz666","description":"Peachy is a very minimal, lightweight, secure, and reactive front-end framework designed for building Single Page Applications (SPAs). It offers a robust state management system (local, global and global with persistence), file-based routing, and a component-based architecture with full reactivity.","archived":false,"fork":false,"pushed_at":"2025-04-10T06:34:13.000Z","size":304,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T07:39:06.333Z","etag":null,"topics":["framework","frontend","frontend-framework","frontend-frameworks","frontend-library","javascript","javascript-framework","react","reactjs"],"latest_commit_sha":null,"homepage":"https://peachy-dev.vercel.app/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sidmaz666.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-25T15:22:11.000Z","updated_at":"2025-04-10T06:34:17.000Z","dependencies_parsed_at":"2025-03-25T16:47:10.785Z","dependency_job_id":null,"html_url":"https://github.com/Sidmaz666/peachy","commit_stats":null,"previous_names":["sidmaz666/peachy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Sidmaz666/peachy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sidmaz666%2Fpeachy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sidmaz666%2Fpeachy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sidmaz666%2Fpeachy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sidmaz666%2Fpeachy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sidmaz666","download_url":"https://codeload.github.com/Sidmaz666/peachy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sidmaz666%2Fpeachy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007791,"owners_count":26084364,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["framework","frontend","frontend-framework","frontend-frameworks","frontend-library","javascript","javascript-framework","react","reactjs"],"created_at":"2025-10-11T16:24:26.941Z","updated_at":"2025-10-11T16:24:29.683Z","avatar_url":"https://github.com/Sidmaz666.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Peachy 🍑\n\nPeachy is a very minimal, lightweight, secure, and reactive front-end framework designed for building Single Page Applications (SPAs). It offers a robust state management system (local, global and global with persistence), file-based routing, and a component-based architecture with full reactivity. It's a fun project where I have learned a lot about how frontend framework works, still a proof of concept though.\n\n![og-image](https://github.com/user-attachments/assets/4896b02b-40e1-48f0-9e9c-7e95c888b13a)\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n- [Project Structure](#project-structure)\n- [Core Concepts](#core-concepts)\n  - [Components](#components)\n  - [State Management](#state-management)\n  - [Routing](#routing)\n  - [Hooks](#hooks)\n- [Configuration](#configuration)\n  - [Babel](#babel)\n  - [Webpack](#webpack)\n  - [Tailwind CSS](#tailwind-css)\n- [Usage](#usage)\n  - [Creating Components](#creating-components)\n  - [Using State](#using-state)\n  - [Global State](#global-state)\n  - [Routing](#routing)\n- [Advanced Topics](#advanced-topics)\n  - [Persistent State](#persistent-state)\n  - [Dynamic Routing](#dynamic-routing)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Getting Started\n\nTo get started with Peachy, clone the repository and install the dependencies:\n\n```bash\nnpx create-peachy-app peachy-app\ncd peachy-app\n```\n\nTo start the development server:\n\n```bash\nnpm start\n```\n\nTo build the project for production:\n\n```bash\nnpm run build\n```\n\n## Project Structure\n\n```\npeachy/\n├── public/\n│   └── index.html\n├── src/\n│   ├── app/\n│   │   ├── about/\n│   │   │   └── page.js\n│   │   ├── blog/\n│   │   │   └── [id]/\n│   │   │       └── page.js\n│   │   ├── layout.js\n│   │   ├── loading.js\n│   │   ├── not-found.js\n│   │   └── page.js\n│   ├── components/\n│   │   └── Header.js\n│   ├── peach/\n│   │   ├── component.js\n│   │   ├── fetch.js\n│   │   ├── router.js\n│   │   ├── state.js\n│   │   └── utils.js\n│   ├── index.css\n│   └── index.js\n├── babel.config.js\n├── package.json\n├── postcss.config.mjs\n├── tailwind.config.js\n└── webpack.config.js\n```\n\n## Core Concepts\n\n### Components\n\nComponents are the building blocks of a Peachy application. They are defined using functions that return JSX.\n\nExample:\n\n```js\nimport { Peachy } from \"@peach/component\";\nimport { Link } from \"@peach/router\";\n\nexport default function Header() {\n  return (\n    \u003cheader className=\"w-full flex justify-between items-center px-4 py-2 bg-black text-xl\"\u003e\n      \u003ch1\u003ePeachy App\u003c/h1\u003e\n      \u003cnav className=\"flex space-x-2 items-center\"\u003e\n        \u003cLink className=\"cursor-pointer\" href=\"/\"\u003e\n          Home\n        \u003c/Link\u003e\n        \u003cLink className=\"cursor-pointer\" href=\"/about\"\u003e\n          About\n        \u003c/Link\u003e\n      \u003c/nav\u003e\n    \u003c/header\u003e\n  );\n}\n```\n\n#### Component Lifecycle\n\nPeachy components support lifecycle methods that allow you to execute code at specific points in a component's lifecycle. These lifecycle methods are defined as properties on the JSX element returned by the component.\n\n- **beforemount**: Runs before the component is mounted to the DOM.\n- **mount**: Runs immediately after the component is mounted to the DOM.\n- **unmount**: Runs when the component is removed from the DOM.\n\n##### Note: `By default any code is executed upon component mounted to DOM.`\n\nExample:\n\n```js\nimport { Peachy } from \"@peach/component\";\n\nexport default function ExampleComponent() {\n  const element = \u003cdiv\u003eHello, Peachy!\u003c/div\u003e;\n\n  // Define lifecycle methods.\n  element.__lifecycle = {\n    beforemount() {\n      console.log(\"Component is about to mount.\");\n    },\n    mount() {\n      console.log(\"Component has been mounted.\");\n    },\n    unmount() {\n      console.log(\"Component is being unmounted.\");\n    },\n  };\n\n  return element;\n}\n```\n\nThe `Peach3dModel` component demonstrates the use of lifecycle methods to manage animations and event listeners. For example, it uses the `mount` method to initialize animations and the `unmount` method to clean up resources like `requestAnimationFrame` and event listeners.\n\n### State Management\n\nPeachy provides a robust state management system with both local and global state capabilities.\n\n#### Local State\n\nLocal state is managed using the `useState` hook.\n\nExample:\n\n```js\nimport { useState, Peachy } from \"@peach/component\";\n\nexport default function HomePage() {\n  const [getCount, setCount] = useState(0);\n\n  return (\n    \u003cdiv\u003e\n      \u003cp\u003eCount: {String(getCount)}\u003c/p\u003e\n      \u003cbutton onClick={() =\u003e setCount(getCount + 1)}\u003eIncrement\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n#### Global State\n\nGlobal state is managed using the `AppState` and `PersistedAppState` classes.\n\nExample:\n\n```js\nimport { Peachy } from \"@peach/component\";\nimport { AppState } from \"@peach/state\";\n\nexport default function AboutPage() {\n  AppState.set(\"lastVisited\", \"About\");\n\n  return (\n    \u003cdiv\u003e\n      \u003ch2\u003eAbout Peachy\u003c/h2\u003e\n      \u003cp\u003eLast visited: {AppState.get(\"lastVisited\")}\u003c/p\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Routing\n\nPeachy uses a file-based routing system similar to Next.js. Routes are defined by the file structure in the `src/app` directory.\n\nExample:\n\n```js\nimport { useState, Peachy } from \"@peach/component\";\nimport { AppState } from \"@peach/state\";\n\nexport default function BlogPostPage({ params }) {\n  const { id } = params;\n  const [getLikes, setLikes] = useState(0);\n\n  AppState.set(\"lastVisited\", `Blog Post ${id}`);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch2\u003eBlog Post #{id}\u003c/h2\u003e\n      \u003cp\u003eLikes: {String(getLikes)}\u003c/p\u003e\n      \u003cbutton onClick={() =\u003e setLikes(getLikes + 1)}\u003eLike\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Hooks\n\nPeachy provides several hooks for managing state and side effects.\n\n- `useState`: Manages local component state.\n- `useGlobalState`: Manages global state with reactivity.\n\n## Configuration\n\n### Babel\n\nBabel is configured to transpile JSX and modern JavaScript features.\n\n```js\nmodule.exports = {\n  presets: [\n    [\"@babel/preset-env\", { targets: \"\u003e 0.25%, not dead\" }],\n    [\n      \"@babel/preset-react\",\n      { pragma: \"Peachy.createElement\", runtime: \"classic\" },\n    ],\n  ],\n};\n```\n\n### Webpack\n\nWebpack is used to bundle the application.\n\n```js\nconst path = require(\"path\");\nconst HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n\nmodule.exports = {\n  entry: \"./src/index.js\",\n  resolve: {\n    extensions: [\".js\", \".jsx\", \".ts\", \".tsx\"],\n    alias: {\n      \"@peach\": path.resolve(__dirname, \"src/peach\"),\n      \"@app\": path.resolve(__dirname, \"src/app\"),\n      \"@components\": path.resolve(__dirname, \"src/components\"),\n      \"@utils\": path.resolve(__dirname, \"src/utils\"),\n      \"@hooks\": path.resolve(__dirname, \"src/hooks\"),\n      \"@assets\": path.resolve(__dirname, \"src/assets\"),\n    },\n  },\n  output: {\n    filename: \"bundle.[contenthash].js\",\n    path: path.resolve(__dirname, \"dist\"),\n    clean: true,\n    publicPath: \"/\",\n  },\n  devServer: {\n    historyApiFallback: true,\n    port: 3000,\n    open: true,\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.jsx?$/,\n        exclude: /node_modules/,\n        use: \"babel-loader\",\n      },\n      {\n        test: /\\.css$/,\n        use: [\"style-loader\", \"css-loader\", \"postcss-loader\"],\n      },\n    ],\n  },\n  plugins: [\n    new HtmlWebpackPlugin({\n      template: \"./public/index.html\",\n      inject: \"body\",\n    }),\n  ],\n  optimization: {\n    minimize: true,\n  },\n};\n```\n\n### Tailwind CSS\n\nTailwind CSS is used for styling.\n\n```js\nmodule.exports = {\n  content: [\"./src/**/*.{js,jsx}\", \"./public/index.html\"],\n  theme: { extend: {} },\n  plugins: [],\n};\n```\n\n## Usage\n\n### Creating Components\n\n- **Define a Component**: Create a function that returns JSX.\n- **Example**:\n\n  ```js\n  import { Peachy } from \"@peach/component\";\n  import { Link } from \"@peach/router\";\n\n  export default function Header() {\n    return (\n      \u003cheader className=\"w-full flex justify-between items-center px-4 py-2 bg-black text-xl\"\u003e\n        \u003ch1\u003ePeachy App\u003c/h1\u003e\n        \u003cnav className=\"flex space-x-2 items-center\"\u003e\n          \u003cLink className=\"cursor-pointer\" href=\"/\"\u003e\n            Home\n          \u003c/Link\u003e\n          \u003cLink className=\"cursor-pointer\" href=\"/about\"\u003e\n            About\n          \u003c/Link\u003e\n        \u003c/nav\u003e\n      \u003c/header\u003e\n    );\n  }\n  ```\n\n### Using State\n\n- **Local State**: Use the `useState` hook to manage local state within a component.\n- **Example**:\n\n  ```js\n  import { useState, Peachy } from \"@peach/component\";\n\n  export default function HomePage() {\n    const [getCount, setCount] = useState(0);\n\n    return (\n      \u003cdiv\u003e\n        \u003cp\u003eCount: {String(getCount)}\u003c/p\u003e\n        \u003cbutton onClick={() =\u003e setCount(getCount + 1)}\u003eIncrement\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n  ```\n\n### Global State\n\n- **Global State**: Use the `AppState` and `PersistedAppState` classes to manage global state.\n- **Example**:\n\n  ```js\n  import { Peachy } from \"@peach/component\";\n  import { AppState } from \"@peach/state\";\n\n  export default function AboutPage() {\n    AppState.set(\"lastVisited\", \"About\");\n\n    return (\n      \u003cdiv\u003e\n        \u003ch2\u003eAbout Peachy\u003c/h2\u003e\n        \u003cp\u003eLast visited: {AppState.get(\"lastVisited\")}\u003c/p\u003e\n      \u003c/div\u003e\n    );\n  }\n  ```\n\n### Routing\n\n- **Define Routes**: Create files in the `src/app` directory to define routes.\n- **Example**:\n\n  ```js\n  import { useState, Peachy } from \"@peach/component\";\n  import { AppState } from \"@peach/state\";\n\n  export default function BlogPostPage({ params }) {\n    const { id } = params;\n    const [getLikes, setLikes] = useState(0);\n\n    AppState.set(\"lastVisited\", `Blog Post ${id}`);\n\n    return (\n      \u003cdiv\u003e\n        \u003ch2\u003eBlog Post #{id}\u003c/h2\u003e\n        \u003cp\u003eLikes: {String(getLikes)}\u003c/p\u003e\n        \u003cbutton onClick={() =\u003e setLikes(getLikes + 1)}\u003eLike\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n  ```\n\n## Advanced Topics\n\n### Persistent State\n\n- **Persistent State**: Use `PersistedAppState` to manage state that persists across sessions using IndexedDB.\n- **Example**:\n\n  ```js\n  import { useGlobalState, Peachy } from \"@peach/component\";\n  import { PersistedAppState } from \"@peach/state\";\n\n  export default function HomePage() {\n    const [getTheme, setTheme] = useGlobalState(PersistedAppState, \"theme\");\n\n    return (\n      \u003cdiv\u003e\n        \u003cp\u003ePersistent Global Theme: {String(getTheme) || \"default\"}\u003c/p\u003e\n        \u003cbutton onClick={() =\u003e setTheme(\"dark\")}\u003eSet Dark Theme\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n  ```\n\n### Dynamic Routing\n\n- **Dynamic Routing**: Use bracket notation in file names to define dynamic routes.\n- **Example**:\n\n  ```js\n  import { useState, Peachy } from \"@peach/component\";\n  import { AppState } from \"@peach/state\";\n\n  export default function BlogPostPage({ params }) {\n    const { id } = params;\n    const [getLikes, setLikes] = useState(0);\n\n    AppState.set(\"lastVisited\", `Blog Post ${id}`);\n\n    return (\n      \u003cdiv\u003e\n        \u003ch2\u003eBlog Post #{id}\u003c/h2\u003e\n        \u003cp\u003eLikes: {String(getLikes)}\u003c/p\u003e\n        \u003cbutton onClick={() =\u003e setLikes(getLikes + 1)}\u003eLike\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n  ```\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidmaz666%2Fpeachy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsidmaz666%2Fpeachy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsidmaz666%2Fpeachy/lists"}