Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Numeric Laravel Package

021/numeric

021/numeric is a lightweight Laravel/PHP package offering straightforward helpers for working with numeric values. It simplifies common number handling and formatting tasks, making it easy to add reliable numeric utilities to your application without extra dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer; Laravel's package discovery should register the service provider automatically:

composer require 021/numeric

If you're on an older Laravel version or discovery is disabled, add the provider manually in config/app.php:

'providers' => [
    // ...
    Numeric\NumericServiceProvider::class,
],

Publish the configuration file so you can inspect the defaults before you build on top of them:

php artisan vendor:publish --tag=numeric-config

Where to look first:

  1. README.md — the authoritative API surface; with a package this small, the README is the documentation.
  2. config/numeric.php — locale, default precision, rounding mode, currency, and separator settings.
  3. src/NumericServiceProvider.php — confirms whether a facade alias, Blade directive, or global helper is registered.
  4. src/ — check whether the entry point is a static utility class, an injectable service, or a Numeric value object; this determines your usage pattern.

First use case: formatting a stored price for display. Assuming a static/facade API:

use Numeric\Numeric;

Numeric::format(1234.5);          // "1,234.50"
Numeric::currency(1234.5);       // "$1,234.50"
Numeric::percent(0.075);         // "7.50%"

Then in Blade:

{{ Numeric::currency($order->total) }}

Do this in one place (a Blade component or API resource) rather than scattering calls through views — see the patterns below.

Implementation Patterns

Wrap it, don't sprinkle it. The highest-value pattern with a single-maintainer numeric package is a thin application-level wrapper so a future swap (or a fork) is a one-file change:

// app/Support/Money.php
final class Money
{
    public static function format(int|float|string $amount, ?string $currency = null): string
    {
        return Numeric::currency($amount, $currency ?? config('shop.currency'));
    }
}

API resources for output, raw values for storage. Keep the database column numeric and only format at the serialization boundary:

class OrderResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'total'          => (float) $this->total,
            'total_display'  => Numeric::currency($this->total),
            'total_compact'  => Numeric::abbreviate($this->total), // "1.2K"
        ];
    }
}

Locale per request. If the package reads locale from config, scope it to the request rather than mutating global config permanently:

public function handle($request, Closure $next)
{
    Numeric::locale($request->user()?->locale ?? config('app.locale'));
    return $next($request);
}

Admin/reporting views are the sweet spot: tables of totals, deltas, and percentages where consistent thousands separators and rounding matter more than raw precision.

Validation and input. If the package ships rules (e.g. Numeric::rule() or a numeric-style rule), prefer Laravel's built-in numeric/decimal rules for validation and reserve this package for presentation. Mixing the two is a common source of "valid but unformattable" bugs.

Testing assertions. Assert on formatted strings, not floats, in feature tests — that's what users see:

$this->assertSame('$1,234.50', Numeric::currency(1234.5));

Pin a couple of these in a NumericFormattingTest so a config change or locale default doesn't silently break invoices.

Byte sizes and durations are a likely secondary use case if the package exposes fileSize() / duration() style helpers; useful for storage dashboards.

Gotchas and Tips

  • Floating point. Any formatter taking float will round at the edges. For money, store integer minor units (cents) and format the integer, or use bcmath. Never round twice (once by the DB, once by the formatter).
  • intl extension. Locale-aware formatting usually delegates to PHP's NumberFormatter. If ext-intl is missing in your container, you'll get either an exception or a silent fallback to a hardcoded en_US style. Check php -m | grep intl in CI and production.
  • Config caching. php artisan config:cache freezes config/numeric.php. Changing locale/currency at runtime via config([...]) will appear to work locally and fail in production. Use the package's runtime setter if one exists; otherwise re-deploy after config changes.
  • Rounding mode defaults. PHP's default is PHP_ROUND_HALF_UP, but finance often wants half-even (banker's rounding). Set it explicitly in the published config and assert it in a test — this is the classic "one cent off on the invoice" bug.
  • Facade alias collisions. A short alias like Numeric can clash with your own class or another package. Use the fully-qualified use Numeric\Numeric; import instead of relying on the global alias.
  • Precision vs. display. Keep precision (calculation) and decimals (display) conceptually separate. Formatting a value to 2 decimals and then doing arithmetic on the string is a real anti-pattern.
  • Debugging. When output looks wrong, isolate the three inputs: value type (int vs float vs numeric string), locale, and separators. Echo Numeric::config() (or dump the resolved config) rather than guessing which layer mangled it.
  • Extension points. If the class is Macroable, add project-specific formatters (Numeric::macro('compactCurrency', ...)) instead of forking. If it isn't, the wrapper class above is your extension point.
  • Maintenance risk. One star and zero dependents means no community bug-finding and no deprecation warnings. Pin an exact version in composer.json, cover your usage with tests, and keep the wrapper thin enough that replacing it with NumberFormatter directly is a morning's work.
  • Semantic versioning. With a 0.x release, expect breaking changes in minor bumps; review the changelog before composer update.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource