<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yoosef alipour</title>
    <description>The latest articles on DEV Community by yoosef alipour (@yoosefap).</description>
    <link>https://dev.to/yoosefap</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1454236%2Fadfc9068-5950-4be9-be2d-5c52bca07e28.jpeg</url>
      <title>DEV Community: yoosef alipour</title>
      <link>https://dev.to/yoosefap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yoosefap"/>
    <language>en</language>
    <item>
      <title>DevDB: A Zero-Setup Database for Faster Local Development</title>
      <dc:creator>yoosef alipour</dc:creator>
      <pubDate>Thu, 02 Jul 2026 04:53:41 +0000</pubDate>
      <link>https://dev.to/yoosefap/devdb-a-zero-setup-database-for-faster-local-development-b0c</link>
      <guid>https://dev.to/yoosefap/devdb-a-zero-setup-database-for-faster-local-development-b0c</guid>
      <description>&lt;p&gt;Starting a new project should be simple.&lt;/p&gt;

&lt;p&gt;Clone the repository, install dependencies, run the app, and start building.&lt;/p&gt;

&lt;p&gt;But in many PHP projects, developers often need to complete several extra steps before they can even see the first page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install MySQL or MariaDB&lt;/li&gt;
&lt;li&gt;Start the database service&lt;/li&gt;
&lt;li&gt;Create a database manually&lt;/li&gt;
&lt;li&gt;Configure usernames, passwords, ports, and environment variables&lt;/li&gt;
&lt;li&gt;Run migrations&lt;/li&gt;
&lt;li&gt;Troubleshoot connection errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For production systems, these steps are completely reasonable.&lt;/p&gt;

&lt;p&gt;But for local development, prototypes, demos, tests, and open-source projects, they can create unnecessary friction.&lt;/p&gt;

&lt;p&gt;That is why &lt;strong&gt;DevDB&lt;/strong&gt; exists.&lt;/p&gt;

&lt;p&gt;DevDB is a lightweight database designed to make local development easier. It helps developers start working on a project without installing and configuring a separate database server.&lt;/p&gt;

&lt;p&gt;The goal is not to replace MySQL, MariaDB, or PostgreSQL in production.&lt;/p&gt;

&lt;p&gt;The goal is to remove friction from development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why DevDB?&lt;/li&gt;
&lt;li&gt;What Problems Does DevDB Solve?&lt;/li&gt;
&lt;li&gt;Who Is DevDB For?&lt;/li&gt;
&lt;li&gt;Using DevDB with Laravel&lt;/li&gt;
&lt;li&gt;DevDB and the Pinoox Ecosystem&lt;/li&gt;
&lt;li&gt;Is DevDB a Replacement for MySQL?&lt;/li&gt;
&lt;li&gt;The Real Value: Less Friction&lt;/li&gt;
&lt;li&gt;What Could Come Next?&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why DevDB?
&lt;/h2&gt;

&lt;p&gt;Every extra setup step makes a project harder to try.&lt;/p&gt;

&lt;p&gt;This is especially important for open-source projects, developer tools, starter kits, and frameworks. If someone needs to install PHP, Composer, MySQL, create a database, configure credentials, and edit environment files before running your project, many people may simply stop before they begin.&lt;/p&gt;

&lt;p&gt;DevDB reduces that setup overhead.&lt;/p&gt;

&lt;p&gt;Instead of asking developers to prepare a full database server, DevDB provides a lightweight local database experience that can work directly with the project.&lt;/p&gt;

&lt;p&gt;The result is a simpler workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone your-project
composer &lt;span class="nb"&gt;install
&lt;/span&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No MySQL installation.&lt;br&gt;
No manual database creation.&lt;br&gt;
No database credentials.&lt;br&gt;
No port configuration.&lt;br&gt;
No unnecessary setup.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Problems Does DevDB Solve?
&lt;/h2&gt;

&lt;p&gt;DevDB is especially useful when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster local project setup&lt;/li&gt;
&lt;li&gt;A database without installing MySQL or MariaDB&lt;/li&gt;
&lt;li&gt;Easier onboarding for new developers&lt;/li&gt;
&lt;li&gt;A lightweight database for prototypes and demos&lt;/li&gt;
&lt;li&gt;Isolated databases for testing&lt;/li&gt;
&lt;li&gt;Offline development support&lt;/li&gt;
&lt;li&gt;A built-in storage solution for CLI or desktop applications&lt;/li&gt;
&lt;li&gt;A simpler developer experience for open-source projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is designed for situations where setting up a full database server is unnecessary or slows down development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Who Is DevDB For?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  PHP Developers
&lt;/h3&gt;

&lt;p&gt;If you work with PHP projects and want to avoid setting up MySQL for every new project, DevDB can make your local environment much faster and easier to manage.&lt;/p&gt;
&lt;h3&gt;
  
  
  Laravel Developers
&lt;/h3&gt;

&lt;p&gt;Laravel already provides excellent tools for database management, including migrations, seeders, factories, and Eloquent ORM.&lt;/p&gt;

&lt;p&gt;However, many Laravel projects still require developers to install and configure MySQL, MariaDB, PostgreSQL, Docker, Laravel Sail, or another local database solution before they can start working.&lt;/p&gt;

&lt;p&gt;DevDB can simplify that first step.&lt;/p&gt;

&lt;p&gt;Instead of requiring a full database server for local development, a Laravel project can use DevDB as a lightweight development database. Developers can clone the project, install dependencies, run migrations, and start building immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone your-laravel-project
&lt;span class="nb"&gt;cd &lt;/span&gt;your-laravel-project
composer &lt;span class="nb"&gt;install
&lt;/span&gt;php artisan migrate
php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Laravel starter kits&lt;/li&gt;
&lt;li&gt;Open-source Laravel packages&lt;/li&gt;
&lt;li&gt;Small and medium Laravel applications&lt;/li&gt;
&lt;li&gt;Rapid prototypes&lt;/li&gt;
&lt;li&gt;Demo projects&lt;/li&gt;
&lt;li&gt;Educational projects&lt;/li&gt;
&lt;li&gt;Local testing environments&lt;/li&gt;
&lt;li&gt;Developer tools built with Laravel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevDB can work as a development-first database option, while production environments continue using MySQL, MariaDB, or PostgreSQL.&lt;/p&gt;

&lt;p&gt;A typical setup could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Local development
DB_CONNECTION=devdb

# Production
DB_CONNECTION=mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps local development simple while allowing production environments to use a scalable and familiar database infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open-Source Maintainers
&lt;/h3&gt;

&lt;p&gt;A project that is easy to install is more likely to be tested, used, and contributed to.&lt;/p&gt;

&lt;p&gt;DevDB can reduce installation steps and make your project more accessible to new contributors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Startups and Small Teams
&lt;/h3&gt;

&lt;p&gt;Early-stage products need speed.&lt;/p&gt;

&lt;p&gt;When your team can start building without spending time on database setup, you can focus more on features, experiments, and product validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI, Desktop, and AI Tools
&lt;/h3&gt;

&lt;p&gt;Many modern tools need local storage for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Settings&lt;/li&gt;
&lt;li&gt;Logs&lt;/li&gt;
&lt;li&gt;Project metadata&lt;/li&gt;
&lt;li&gt;Local history&lt;/li&gt;
&lt;li&gt;Cached data&lt;/li&gt;
&lt;li&gt;Agent memory&lt;/li&gt;
&lt;li&gt;Generated content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevDB can provide a lightweight database layer without requiring users to install and manage a separate database server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using DevDB with Laravel
&lt;/h2&gt;

&lt;p&gt;DevDB can be especially valuable in Laravel projects where the goal is to provide a simple and fast local development experience.&lt;/p&gt;

&lt;p&gt;A Laravel application could include DevDB as a development dependency and configure it automatically during installation.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require pinoox/devdb &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the project can use a dedicated database connection inside &lt;code&gt;config/database.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'devdb'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'driver'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'devdb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'database'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;database_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'devdb/database.devdb'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once configured, developers can continue using familiar Laravel commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate
php artisan db:seed
php artisan &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not to change the Laravel development workflow.&lt;/p&gt;

&lt;p&gt;The goal is to make the workflow easier to start.&lt;/p&gt;

&lt;p&gt;Developers can still use migrations, seeders, factories, Eloquent models, relationships, and Laravel testing tools. DevDB simply removes the need to install and configure a separate database server for local development.&lt;/p&gt;

&lt;h2&gt;
  
  
  DevDB and the Pinoox Ecosystem
&lt;/h2&gt;

&lt;p&gt;DevDB is designed to improve the development experience inside the Pinoox ecosystem.&lt;/p&gt;

&lt;p&gt;For example, a developer can create a project, run migrations, and start building without first installing MySQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pinx new my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
pinx migrate
pinx dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the development workflow much more approachable, especially for developers who want to quickly test an application, build a prototype, or contribute to a project.&lt;/p&gt;

&lt;p&gt;Instead of spending time configuring infrastructure, developers can focus on writing features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is DevDB a Replacement for MySQL?
&lt;/h2&gt;

&lt;p&gt;Not exactly.&lt;/p&gt;

&lt;p&gt;DevDB is not intended to replace MySQL, MariaDB, or PostgreSQL in every situation.&lt;/p&gt;

&lt;p&gt;For production applications with large datasets, high concurrency, multiple services, replication, advanced monitoring, or complex infrastructure requirements, traditional database servers are still the better choice.&lt;/p&gt;

&lt;p&gt;DevDB is best used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local development&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Prototypes&lt;/li&gt;
&lt;li&gt;Small internal tools&lt;/li&gt;
&lt;li&gt;CLI applications&lt;/li&gt;
&lt;li&gt;Desktop applications&lt;/li&gt;
&lt;li&gt;Open-source demos&lt;/li&gt;
&lt;li&gt;Fast project setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A practical workflow could look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Recommended Database&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local Development&lt;/td&gt;
&lt;td&gt;DevDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated Testing&lt;/td&gt;
&lt;td&gt;DevDB or isolated test database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;td&gt;MySQL, MariaDB, or PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This approach keeps development fast while still allowing production systems to use powerful and scalable database infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Value: Less Friction
&lt;/h2&gt;

&lt;p&gt;DevDB is not only about using a lightweight database.&lt;/p&gt;

&lt;p&gt;Its real value is improving the developer experience.&lt;/p&gt;

&lt;p&gt;When developers can run a project without installing extra services, configuring credentials, or debugging database connections, they can start building much faster.&lt;/p&gt;

&lt;p&gt;This improves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developer onboarding&lt;/li&gt;
&lt;li&gt;Open-source adoption&lt;/li&gt;
&lt;li&gt;Prototype speed&lt;/li&gt;
&lt;li&gt;Local development workflows&lt;/li&gt;
&lt;li&gt;Team productivity&lt;/li&gt;
&lt;li&gt;Project accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good development environment should help developers focus on the product, not on setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Could Come Next?
&lt;/h2&gt;

&lt;p&gt;DevDB can grow beyond a lightweight local database.&lt;/p&gt;

&lt;p&gt;Possible future features could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A visual database browser&lt;/li&gt;
&lt;li&gt;Built-in table and record management&lt;/li&gt;
&lt;li&gt;Query execution tools&lt;/li&gt;
&lt;li&gt;Migration management&lt;/li&gt;
&lt;li&gt;Import and export support&lt;/li&gt;
&lt;li&gt;Test database generation&lt;/li&gt;
&lt;li&gt;Database snapshots&lt;/li&gt;
&lt;li&gt;AI-assisted schema analysis&lt;/li&gt;
&lt;li&gt;Easy migration from DevDB to MySQL or PostgreSQL&lt;/li&gt;
&lt;li&gt;Integration with desktop and CLI developer tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features could turn DevDB into a complete local development database experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;DevDB solves a simple but common problem:&lt;/p&gt;

&lt;p&gt;You should not need to install and configure a full database server just to start developing a project.&lt;/p&gt;

&lt;p&gt;It is not designed to replace production databases.&lt;/p&gt;

&lt;p&gt;It is designed to make development faster, easier, and more accessible.&lt;/p&gt;

&lt;p&gt;If you want to reduce setup time, simplify onboarding, create better open-source developer experiences, or build tools that need local storage without extra dependencies, DevDB can be a useful part of your workflow.&lt;/p&gt;

&lt;p&gt;Explore DevDB on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/pinoox/devdb" rel="noopener noreferrer"&gt;https://github.com/pinoox/devdb&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>php</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Built an Open-Source AI Coding Assistant That Works Like Cursor and Codex — But It's Free</title>
      <dc:creator>yoosef alipour</dc:creator>
      <pubDate>Sat, 27 Jun 2026 21:04:28 +0000</pubDate>
      <link>https://dev.to/yoosefap/i-built-an-open-source-ai-coding-assistant-that-works-like-cursor-and-codex-but-its-free-4gaf</link>
      <guid>https://dev.to/yoosefap/i-built-an-open-source-ai-coding-assistant-that-works-like-cursor-and-codex-but-its-free-4gaf</guid>
      <description>&lt;p&gt;AI coding assistants have completely changed how many of us write software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts8grywmced4jhqi2dz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts8grywmced4jhqi2dz3.png" alt=" " width="800" height="579"&gt;&lt;/a&gt;&lt;br&gt;
Today it's normal to ask an AI to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a new feature&lt;/li&gt;
&lt;li&gt;Fix bugs&lt;/li&gt;
&lt;li&gt;Refactor code&lt;/li&gt;
&lt;li&gt;Generate tests&lt;/li&gt;
&lt;li&gt;Explain unfamiliar code&lt;/li&gt;
&lt;li&gt;Update documentation&lt;/li&gt;
&lt;li&gt;Execute project commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is that most modern AI coding tools come with at least one of these limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They require an account.&lt;/li&gt;
&lt;li&gt;They're tied to a specific editor.&lt;/li&gt;
&lt;li&gt;Many useful features are locked behind paid plans.&lt;/li&gt;
&lt;li&gt;They're not fully open source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;Instead of building another AI chat application, I wanted to create a lightweight desktop tool that behaves like an AI software engineer.&lt;/p&gt;

&lt;p&gt;You describe what you want in natural language, and the assistant works directly inside your project.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create a REST API for authentication."&lt;/p&gt;

&lt;p&gt;"Refactor this module using the repository pattern."&lt;/p&gt;

&lt;p&gt;"Write unit tests for this service."&lt;/p&gt;

&lt;p&gt;"Explain why this function is slow."&lt;/p&gt;

&lt;p&gt;"Rename these files and update imports."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is to spend less time switching between tools and more time building software.&lt;/p&gt;




&lt;h2&gt;
  
  
  Meet Movo
&lt;/h2&gt;

&lt;p&gt;Movo is an open-source desktop AI coding assistant designed for developers.&lt;/p&gt;

&lt;p&gt;It focuses on making AI-powered development simple and accessible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🤖 AI-powered coding assistant&lt;/li&gt;
&lt;li&gt;💬 Natural language interface&lt;/li&gt;
&lt;li&gt;🐞 Bug fixing&lt;/li&gt;
&lt;li&gt;✨ Code generation&lt;/li&gt;
&lt;li&gt;♻️ Refactoring&lt;/li&gt;
&lt;li&gt;🧪 Test generation&lt;/li&gt;
&lt;li&gt;📝 Documentation generation&lt;/li&gt;
&lt;li&gt;⚡ Execute project commands&lt;/li&gt;
&lt;li&gt;🔌 MCP support&lt;/li&gt;
&lt;li&gt;📦 Skills &amp;amp; Rules support&lt;/li&gt;
&lt;li&gt;🌍 Windows, macOS and Linux&lt;/li&gt;
&lt;li&gt;🔓 Completely open source&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Open Source?
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages of open source AI tools is transparency.&lt;/p&gt;

&lt;p&gt;Developers can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audit the source code&lt;/li&gt;
&lt;li&gt;Customize workflows&lt;/li&gt;
&lt;li&gt;Add new capabilities&lt;/li&gt;
&lt;li&gt;Integrate their own models&lt;/li&gt;
&lt;li&gt;Contribute improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of being locked into a specific ecosystem, the community can shape the project together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current Status
&lt;/h2&gt;

&lt;p&gt;Movo is still in its early stages.&lt;/p&gt;

&lt;p&gt;The core experience is already working, but there are many features planned, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better agent workflows&lt;/li&gt;
&lt;li&gt;More MCP integrations&lt;/li&gt;
&lt;li&gt;Additional Skills&lt;/li&gt;
&lt;li&gt;Improved project understanding&lt;/li&gt;
&lt;li&gt;More customization options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback from developers will play a huge role in deciding where the project goes next.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you'd like to test it, contribute, or simply follow the project, check out the GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/movobox/movo" rel="noopener noreferrer"&gt;https://github.com/movobox/movo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contributions, ideas, bug reports, and feature requests are always welcome.&lt;/p&gt;

&lt;p&gt;If you find the project interesting, consider giving it a ⭐ on GitHub—it really helps open-source projects grow.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Pinion: Resumable File Uploads for PHP</title>
      <dc:creator>yoosef alipour</dc:creator>
      <pubDate>Wed, 17 Jun 2026 23:34:06 +0000</pubDate>
      <link>https://dev.to/yoosefap/pinion-resumable-file-uploads-for-php-189p</link>
      <guid>https://dev.to/yoosefap/pinion-resumable-file-uploads-for-php-189p</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;(Without Fighting &lt;code&gt;upload_max_filesize&lt;/code&gt;)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You deploy your app. A user picks a 400 MB video. They hit upload. The progress bar freezes. Then — nothing.&lt;/p&gt;

&lt;p&gt;You check the logs. &lt;code&gt;POST Content-Length&lt;/code&gt; exceeded &lt;code&gt;post_max_size&lt;/code&gt;. Again.&lt;/p&gt;

&lt;p&gt;We've all been there. The fix is usually "raise PHP limits" or "use S3." Both work — until you're on shared hosting, a legacy VPS, or a client who won't touch &lt;code&gt;php.ini&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;strong&gt;Pinion&lt;/strong&gt; solves.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Pinion?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pinoox/pinion" rel="noopener noreferrer"&gt;Pinion&lt;/a&gt; is an open-source &lt;strong&gt;resumable chunked upload protocol&lt;/strong&gt; for PHP.&lt;/p&gt;

&lt;p&gt;Instead of one giant &lt;code&gt;multipart/form-data&lt;/code&gt; request, the browser sends the file in small parts (default: 5 MB). The server stores each part, then assembles the final file on disk.&lt;/p&gt;

&lt;p&gt;Three steps. That's the whole contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;init → upload parts → complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Registry&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pinoox/pinion&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Packagist&lt;/td&gt;
&lt;td&gt;PHP server engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@pinooxhq/pinion-client&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;Browser client&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Protocol id: &lt;code&gt;pinion&lt;/code&gt; · version: &lt;code&gt;2&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just use S3?
&lt;/h2&gt;

&lt;p&gt;Object storage is great. But sometimes you need files &lt;strong&gt;on your server&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A CMS media library on local disk&lt;/li&gt;
&lt;li&gt;A Laravel app without cloud budget&lt;/li&gt;
&lt;li&gt;Shared hosting with no S3 SDK&lt;/li&gt;
&lt;li&gt;An admin panel behind a simple PHP API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pinion isn't a CDN or a storage service. It's a &lt;strong&gt;protocol&lt;/strong&gt; — a stable HTTP contract that works in plain PHP, Laravel, or Pinoox.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works (30-second version)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sequenceDiagram
    participant Browser
    participant API
    participant Disk

    Browser-&amp;gt;&amp;gt;API: POST /init (filename, size, fingerprint)
    API--&amp;gt;&amp;gt;Browser: upload_id, chunk_size, missing_indexes

    loop Each part
        Browser-&amp;gt;&amp;gt;API: POST /upload (chunk + SHA-256 hash)
        API-&amp;gt;&amp;gt;Disk: store part
    end

    Browser-&amp;gt;&amp;gt;API: POST /complete
    API-&amp;gt;&amp;gt;Disk: assemble file
    API--&amp;gt;&amp;gt;Browser: done ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resume&lt;/strong&gt; is built in. The client sends a &lt;code&gt;fingerprint&lt;/code&gt; (&lt;code&gt;name:size:lastModified:type&lt;/code&gt;). If the connection drops, the same file picks up where it left off — only missing parts are re-uploaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrity&lt;/strong&gt; too. Each part gets a SHA-256 &lt;code&gt;chunk_hash&lt;/code&gt;. The server can reject corrupted chunks before they pollute your disk.&lt;/p&gt;




&lt;h2&gt;
  
  
  Server side: 10 lines of PHP
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require pinoox/pinion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Pinoox\Pinion\Pinion&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Pinion&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'storage_path'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/tmp/pinion'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pinion&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'destination'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'uploads/videos'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nv"&gt;$handler&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$handler&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_FILES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'chunk'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$handler&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wire five routes under any prefix you like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/v1/upload/init
POST /api/v1/upload/upload
POST /api/v1/upload/complete
GET  /api/v1/upload/status/{id}
POST /api/v1/upload/abort/{id}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HttpHandler&lt;/code&gt; returns plain arrays — map them to JSON in Laravel, Pinoox, or raw PHP. No framework lock-in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser side: one function, zero extra deps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @pinooxhq/pinion-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;uploadFile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@pinooxhq/pinion-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/v1/upload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;unwrapPreset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinoox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onProgress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eta&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% · &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; B/s · ETA &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;eta&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Axios required. The client uses native &lt;code&gt;fetch&lt;/code&gt; by default. Already on Axios? Pass it in — you get per-chunk &lt;code&gt;onUploadProgress&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;baseURL&lt;/code&gt; is just the &lt;strong&gt;prefix&lt;/strong&gt;. The client calls &lt;code&gt;/init&lt;/code&gt;, &lt;code&gt;/upload&lt;/code&gt;, &lt;code&gt;/complete&lt;/code&gt; for you. You don't loop over chunks manually unless you want to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level up when you need to
&lt;/h2&gt;

&lt;p&gt;Start simple. Grow when the project demands it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One upload button&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uploadFile(file, options)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reusable uploader&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pinion({ baseURL }).for(file).upload()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch + cancel + hooks&lt;/td&gt;
&lt;td&gt;&lt;code&gt;createPinionFetch(options)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full manual control&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;client.api.init()&lt;/code&gt; → &lt;code&gt;uploadPart()&lt;/code&gt; → &lt;code&gt;complete()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Small files? Skip Pinion entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/v1/upload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// file under 8 MB — use your normal single POST&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What I like about the design
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Boring HTTP.&lt;/strong&gt; JSON for &lt;code&gt;init&lt;/code&gt;/&lt;code&gt;complete&lt;/code&gt;, &lt;code&gt;FormData&lt;/code&gt; for chunks. No WebSockets, no custom binary framing. Debug with curl or DevTools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Parallel by default.&lt;/strong&gt; Upload 2 parts at once. Retry failed parts with backoff. Progress includes speed and ETA — not just a percentage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Framework adapters, not framework prison.&lt;/strong&gt; Core engine is pure PHP. Laravel gets a Service Provider and Facade. Pinoox gets a Portal and CLI (&lt;code&gt;pinion:list&lt;/code&gt;, &lt;code&gt;pinion:clean&lt;/code&gt;). Plain PHP gets &lt;code&gt;HttpHandler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Unwrap presets.&lt;/strong&gt; Your API returns &lt;code&gt;{ data: { … } }&lt;/code&gt;? Set &lt;code&gt;unwrapPreset: 'pinoox'&lt;/code&gt;. Flat JSON? Use &lt;code&gt;'flat'&lt;/code&gt;. The client adapts; you don't rewrite parsers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-world fit
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Pinion helps because…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shared hosting (20 MB cap)&lt;/td&gt;
&lt;td&gt;5 MB parts fit under the limit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile / flaky Wi-Fi&lt;/td&gt;
&lt;td&gt;Resume after disconnect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin upload panels&lt;/td&gt;
&lt;td&gt;Progress bar with real bytes + ETA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video courses / archives&lt;/td&gt;
&lt;td&gt;GB-scale without touching &lt;code&gt;php.ini&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-framework teams&lt;/td&gt;
&lt;td&gt;Same protocol, PHP + JS packages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Server&lt;/span&gt;
composer require pinoox/pinion

&lt;span class="c"&gt;# Browser&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @pinooxhq/pinion-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/pinoox/pinion" rel="noopener noreferrer"&gt;github.com/pinoox/pinion&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP docs:&lt;/strong&gt; &lt;a href="https://github.com/pinoox/pinion/blob/master/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client docs:&lt;/strong&gt; &lt;a href="https://github.com/pinoox/pinion/tree/master/client" rel="noopener noreferrer"&gt;client/README&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've fought &lt;code&gt;upload_max_filesize&lt;/code&gt; one too many times, Pinion might save your next Friday night.&lt;/p&gt;

&lt;p&gt;Questions, issues, or war stories welcome in the repo. 🙌&lt;/p&gt;

</description>
      <category>php</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Numera 2.1: Laravel Support, 184 Languages, and a Whole Lot More</title>
      <dc:creator>yoosef alipour</dc:creator>
      <pubDate>Mon, 25 May 2026 19:58:19 +0000</pubDate>
      <link>https://dev.to/yoosefap/numera-21-laravel-support-184-languages-and-a-whole-lot-more-2bmf</link>
      <guid>https://dev.to/yoosefap/numera-21-laravel-support-184-languages-and-a-whole-lot-more-2bmf</guid>
      <description>&lt;p&gt;&lt;em&gt;A follow-up to &lt;a href="https://dev.to/yoosefap/numera-a-php-library-for-number-to-words-conversion-1g25"&gt;Numera: A PHP Library for Number to Words Conversion&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;When I published the first article about Numera back in 2024, it was a simple library with one goal: convert numbers to words in PHP. The response was encouraging, and the community feedback (including the great note about &lt;code&gt;en&lt;/code&gt; vs &lt;code&gt;en-US&lt;/code&gt;) pushed me to think bigger.&lt;/p&gt;

&lt;p&gt;Today, &lt;strong&gt;Numera 2.1 is out&lt;/strong&gt; — and it's a different beast. Same simple API, but now with 184 language packs, a Laravel bridge, GitHub Actions CI, and a set of new reading modes that cover real-world use cases I kept running into.&lt;/p&gt;

&lt;p&gt;Let me walk you through what's new.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Plain PHP&lt;/span&gt;
composer require pinoox/numera:^2.1

&lt;span class="c"&gt;# Laravel 9 / 10 / 11&lt;/span&gt;
composer require pinoox/numera-laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What's new in 2.1
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Laravel integration — first-class
&lt;/h3&gt;

&lt;p&gt;The most-requested feature. Install &lt;code&gt;pinoox/numera-laravel&lt;/code&gt; and you get auto-discovery, a Facade, and a publishable config — nothing to wire up manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Pinoox\Numera\Laravel\Facades\Numera&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;               &lt;span class="c1"&gt;// two thousand twenty-four&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;toCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'USD'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// one thousand, five hundred dollars&lt;/span&gt;

&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;setLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// هزار و پانصد&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Publish the config to set your default locale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan vendor:publish &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;numera-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/numera.php&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'default_locale'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'fallback_locale'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All public methods work on the Facade — &lt;code&gt;n2w&lt;/code&gt;, &lt;code&gt;w2n&lt;/code&gt;, &lt;code&gt;toOrdinal&lt;/code&gt;, &lt;code&gt;toCurrency&lt;/code&gt;, &lt;code&gt;withUnit&lt;/code&gt;, &lt;code&gt;toWeekday&lt;/code&gt;, &lt;code&gt;translateTo&lt;/code&gt;, and all the new ones below.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. 184 language packs with regional variants
&lt;/h3&gt;

&lt;p&gt;Numera now ships with &lt;strong&gt;184 ISO 639-1 language packs&lt;/strong&gt; plus regional variants like &lt;code&gt;en-US&lt;/code&gt;, &lt;code&gt;en-GB&lt;/code&gt;, &lt;code&gt;fa-IR&lt;/code&gt;, and &lt;code&gt;de-AT&lt;/code&gt;. Regional files only declare overrides; everything else is inherited from the parent locale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en-GB'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GBP'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// three pounds and one penny&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa-IR'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getWeekdays&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;            &lt;span class="c1"&gt;// starts Saturday&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'de-AT'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStrategyName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;        &lt;span class="c1"&gt;// german (inherited from de)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Languages with special compounding rules use a &lt;code&gt;strategy&lt;/code&gt; system:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Locales&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;german&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;de&lt;/code&gt;, &lt;code&gt;de-*&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Inverted tens: &lt;em&gt;einundzwanzig&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;french&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fr&lt;/code&gt;, &lt;code&gt;fr-*&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Vigesimal 70–99: &lt;em&gt;quatre-vingts&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;multiplier_tens&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;ms&lt;/code&gt;, &lt;code&gt;vi&lt;/code&gt;, …&lt;/td&gt;
&lt;td&gt;2×10+3, not 2+10+3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Most others&lt;/td&gt;
&lt;td&gt;English-style place value&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  3. Smart input formats
&lt;/h3&gt;

&lt;p&gt;Different regions format numbers differently. Numera now handles them all automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// European format (dot as thousands, comma as decimal)&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.234.567,89'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Swiss format (apostrophe as thousands)&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1'234'567.89"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Persian/Arabic digits&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'۱۲۳۴'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// converted to 1234 automatically&lt;/span&gt;

&lt;span class="c1"&gt;// Underscore separator (PHP/Python style)&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1_000_000'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// one million&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also detect the format explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;detectFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.234,56'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 'european'&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;detectFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1'000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// 'swiss'&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;detectFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'۱۲۳'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// 'persian'&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;detectFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1_000_000'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'underscore'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Fraction reading
&lt;/h3&gt;

&lt;p&gt;Common fractions are now read naturally instead of as raw decimals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// one half&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// one quarter&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// three quarters&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// one and a half&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.333&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// two and one third&lt;/span&gt;

&lt;span class="c1"&gt;// Persian&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// نیم&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// یک و نیم&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short alias: &lt;code&gt;n2f()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Year reading
&lt;/h3&gt;

&lt;p&gt;Years are spoken differently from cardinals — "nineteen ninety-nine", not "one thousand nine hundred ninety-nine".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// nineteen ninety-nine&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// two thousand&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// two thousand and five&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// twenty twenty-four&lt;/span&gt;

&lt;span class="c1"&gt;// Persian falls back to standard cardinal&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1402&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// هزار و چهارصد و دو&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short alias: &lt;code&gt;n2y()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Phone number reading
&lt;/h3&gt;

&lt;p&gt;Read phone numbers digit-by-digit, preserving the grouping from the input format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toPhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'+1 415 555 0172'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// plus one, four one five, five five five, zero one seven two&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toPhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'021-8834-1100'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// zero two one, eight eight three four, one one zero zero&lt;/span&gt;

&lt;span class="c1"&gt;// Persian digits work too&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toPhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'۰۲۱-۸۸۳۴'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// zero two one, eight eight three four&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short alias: &lt;code&gt;n2p()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Roman numerals
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toRoman&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// MMXXIV&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toRoman&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// MCMXCIX&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fromRoman&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XIV'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 14&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fromRoman&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'xl'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 40 (case-insensitive)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Range: 1–3999. Throws &lt;code&gt;InvalidArgumentException&lt;/code&gt; outside that range.&lt;/p&gt;

&lt;p&gt;Short alias: &lt;code&gt;n2r()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  8. IP address and version string reading
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toIp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'192.168.1.1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// one ninety-two dot one sixty-eight dot one dot one&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2.14.0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// two point fourteen point zero&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.0.0-beta'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// one point zero point zero dash beta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short aliases: &lt;code&gt;n2ip()&lt;/code&gt;, &lt;code&gt;n2v()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  9. GitHub Actions CI
&lt;/h3&gt;

&lt;p&gt;Numera now runs a full test matrix on every push and PR — PHP 8.0, 8.1, 8.2, and 8.3. No more "works on my machine" surprises.&lt;/p&gt;




&lt;h2&gt;
  
  
  What still carries over from 2.0
&lt;/h2&gt;

&lt;p&gt;Everything from the previous release still works exactly the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cardinals&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2w&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4454545156&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// four billion, four hundred fifty-four million, ...&lt;/span&gt;

&lt;span class="c1"&gt;// Ordinals&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2o&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// twenty-first&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2o&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// بیست و یکم&lt;/span&gt;

&lt;span class="c1"&gt;// Currency&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1250.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'USD'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// one thousand, two hundred fifty dollars and fifty cents&lt;/span&gt;

&lt;span class="c1"&gt;// Units&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withUnit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hour'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// five hours&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withUnit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'day'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// یک روز&lt;/span&gt;

&lt;span class="c1"&gt;// Weekdays&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toWeekday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// شنبه&lt;/span&gt;

&lt;span class="c1"&gt;// Cross-locale translation&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;translateTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'دویست و یک'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// two hundred one&lt;/span&gt;
&lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;translateTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'two hundred one'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// دویست و یک&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Real-world use cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Invoice systems&lt;/strong&gt; — convert totals to words for legal documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fa'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15750000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'IRR'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// پانزده میلیون و هفتصد و پنجاه هزار ریال&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Accessibility&lt;/strong&gt; — read version numbers and IPs aloud in screen-reader friendly text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'3.2.1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// three point two point one&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Financial reports&lt;/strong&gt; — ordinals for ranking, fractions for ratios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;n2o&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// first&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toFraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// one half&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Forms and CRMs&lt;/strong&gt; — read user-entered phone numbers back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toPhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'+44 20 7946 0958'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/pinoox/numera" rel="noopener noreferrer"&gt;github.com/pinoox/numera&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Packagist: &lt;a href="https://packagist.org/packages/pinoox/numera" rel="noopener noreferrer"&gt;packagist.org/packages/pinoox/numera&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Laravel bridge: &lt;a href="https://packagist.org/packages/pinoox/numera-laravel" rel="noopener noreferrer"&gt;packagist.org/packages/pinoox/numera-laravel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Translation Guide: &lt;a href="https://github.com/pinoox/numera/blob/master/TranslationGuide.md" rel="noopener noreferrer"&gt;TranslationGuide.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CHANGELOG: &lt;a href="https://github.com/pinoox/numera/blob/master/CHANGELOG.md" rel="noopener noreferrer"&gt;CHANGELOG.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contributions are welcome — especially language packs. If you speak a language that isn't fully covered yet, the Translation Guide walks you through adding one in minutes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #php #laravel #composer #opensource&lt;/em&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Numera: A PHP Library for Number to Words Conversion</title>
      <dc:creator>yoosef alipour</dc:creator>
      <pubDate>Sun, 28 Apr 2024 08:34:07 +0000</pubDate>
      <link>https://dev.to/yoosefap/numera-a-php-library-for-number-to-words-conversion-1g25</link>
      <guid>https://dev.to/yoosefap/numera-a-php-library-for-number-to-words-conversion-1g25</guid>
      <description>&lt;p&gt;As a developer, you may have encountered situations where you need to convert numbers to words or vice versa. This can be a tedious task, especially when dealing with large numbers or multiple languages. That's where Numera comes in - a powerful PHP library that makes number to words conversion a breeze.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore the features and benefits of Numera, and show you how to use it in your PHP projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Numera?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Numera is a PHP library that provides a simple and efficient way to convert numbers to words and vice versa. It supports multiple languages, including English and Persian, with more languages to come. Numera is designed to be easy to use and extend, making it a great tool for any PHP project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features of Numera&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Numera has a range of features that make it a powerful tool for number to words conversion. Some of the key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Number to Words Conversion&lt;/strong&gt;: Convert numbers to words in a variety of languages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Words to Number Conversion&lt;/strong&gt;: Convert words to numbers in a variety of languages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camel Case Support&lt;/strong&gt;: Output words in camel case for easier readability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Language Support&lt;/strong&gt;: Supports multiple languages, with more languages to come.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to Use&lt;/strong&gt;: Simple and intuitive API makes it easy to use Numera in your projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to Extend&lt;/strong&gt;: Numera is designed to be easy to extend, making it simple to add support for new languages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Install via Composer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can install Numera using Composer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require pinoox/numera
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to Use Numera&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using Numera is straightforward. Here's an example of how to convert a number to words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Pino\Numera&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$numera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Numera&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Initialize with English locale&lt;/span&gt;
&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$numera&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;convertToWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4454545156&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Output: "four billion, four hundred fifty-four million, five hundred forty-five thousand, one hundred fifty-six"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Converting words to numbers is just as easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$numera&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;convertToNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'four billion, four hundred fifty-four million, five hundred forty-five thousand, one hundred fifty-six'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Output: 4454545156&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits of Using Numera&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are several benefits to using Numera in your PHP projects. Some of the key benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Saves Time&lt;/strong&gt;: Numera saves you time and effort by providing a simple and efficient way to convert numbers to words and vice versa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improves Readability&lt;/strong&gt;: Numera's camel case support makes it easy to output words in a readable format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Language Support&lt;/strong&gt;: Numera's support for multiple languages makes it a great tool for international projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to Use&lt;/strong&gt;: Numera's simple and intuitive API makes it easy to use, even for developers with limited experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Get Started with Numera&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get started with Numera, head over to the &lt;a href="https://github.com/pinoox/numera"&gt;Numera GitHub repository&lt;/a&gt; and follow the installation instructions. You can also check out the &lt;a href="https://github.com/pinoox/numera/blob/master/README.md"&gt;Numera documentation&lt;/a&gt; for more information on how to use Numera in your projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Numera is a powerful and flexible PHP library that makes number to words conversion a breeze. With its support for multiple languages, camel case output, and easy-to-use API, Numera is a great tool for any PHP project. Whether you're working on a simple website or a complex application, Numera is definitely worth considering.&lt;/p&gt;

</description>
      <category>php</category>
      <category>composer</category>
      <category>develper</category>
      <category>number</category>
    </item>
  </channel>
</rss>
