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

Livewire Datepicker Laravel Package

karnoweb/livewire-datepicker

Jalali and Gregorian datepicker for Livewire 3 and Alpine.js with wire:model support for single, range, and multiple dates, min/max limits, themes, RTL, and Gregorian export for storage. No npm or Vite setup required.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a presentation-layer Blade component (<x-jalali-datepicker />) that binds through wire:model and delegates all calendar math to two layers: morilog/jalali on the server (exposed as gregorian_to_jalali() / jalali_to_gregorian() helpers) and a bundled jalaali-js on the client. Architecturally that is the right split for a Laravel app: the picker owns display and interaction, PHP owns conversion, and the persistence boundary stays Gregorian via export-calendar="gregorian" + export-format="Y-m-d". That last attribute is the single most important design decision for us — it means Jalali is a UI concern and downstream Carbon logic, DB indexes, reporting, and API contracts remain ISO-dated and untouched.

The wire:model payload is mode-dependent, and this is a contract we must design around rather than discover in production:

Mode Payload
single scalar date string in export-format
:range="true" object {start, end}
:multiple="true" array of date strings (optionally capped by max-selections)

Integration feasibility. High for a single Laravel monolith on Livewire 3. Install is one composer require, no npm/Vite entry, no jQuery, script auto-loads when the component is used. Optional publish tags cover config, views, and raw assets. Two things temper the "easy" verdict: the version matrix is genuinely confusing, and the documentation set contradicts itself.

  • README Requirements says PHP ^8.2, Laravel ^11.0|^12.0, Livewire ^3.0|^4.0.
  • The changelog says the 13.0.0 line requires PHP 8.3 and illuminate/support ^13.0, and that L11–12 should stay on ^1.0.
  • The description says "Livewire 3" only, while the README claims Livewire 4.
  • The bundled third-party getting-started doc references Livewire 2.x and a livewire:livewire-datepicker tag that the README does not use.

Treat the README plus composer.json as normative and verify the rest against src/ before committing to a plan.

Technical risk. Concentrated in supply chain and verification, not in the happy path.

  • Vendor risk (high): 0 stars, 0 dependents, single-vendor package, no evidence of CI badges, security policy, or an automated test suite. Maturity signals listed are only readme, changelog. There is no community backstop if the maintainer stops tagging releases.
  • Version-line coupling (medium): the package mirrors Laravel majors (^1.0 vs ^13.0). Every Laravel upgrade becomes a dependency-upgrade event with a small vendor in the critical path of our form layer.
  • Calendar correctness (medium): two independent implementations (Borkowski jalaali-js in the browser, morilog/jalali in PHP) must agree on leap years and month lengths. Jalali leap-year handling (Esfand 29 vs 30) and date-boundary/timezone behavior are the classic defect sites.
  • Asset delivery (medium): the package serves its own bundled JS rather than going through Vite. That is convenient but raises CSP, SRI, cache-busting, and multi-tenant/CDN questions we would normally answer in our own pipeline.
  • Livewire 4 claim (unverified): support is asserted in the README but the changelog only evidences Laravel 13 work. We should assume nothing until one component renders correctly end-to-end on our exact Livewire version.

Key questions (to close in the spike before any commitment):

  1. Commit cadence, open-issue backlog, and tag hygiene over the last 12 months — is this actively maintained or a personal utility?
  2. Is dist/datepicker.js committed and versioned with each tag, and does the asset-serving route work behind our CSP and asset-cache configuration?
  3. Is there any PHPUnit/browser test coverage, and specifically any leap-year and DST edge-case tests?
  4. Does the component cooperate with wire:model.live, .blur, and .defer, and how are validation errors displayed?
  5. On Livewire 4, does the Alpine component register without colliding with Livewire's bundled Alpine instance?
  6. What exactly does the server receive for range and multiple modes, and is that payload stable across ^1.0 and ^13.0?
  7. Are the accessibility claims (ARIA, keyboard navigation) credible, or marketing copy?
  8. Can we take a fork under MIT if upstream stalls — and has legal signed off on that as the exit path?

Integration Approach

Stack fit. Target Laravel 11–12 on PHP 8.2 with Livewire 3 → use karnoweb/livewire-datepicker:^1.0. Target Laravel 13 on PHP 8.3 → use ^13.0. Do not try to back-port the 13.x line, and do not adopt this package at all on Inertia/Vue/React front-ends, Livewire 2, or any stack where the input layer is not Blade-rendered. The jalali component prefix is a deliberate collision-avoidance measure against Mary-UI's <x-datepicker>; if we already run Mary-UI, keep both prefixes intact and never alias globally.

Migration path. This is a brownfield swap of existing date inputs (native <input type="date">, Flatpickr, or a vendor UI kit). Run it behind one internal wrapper so the vendor tag appears exactly once in the codebase:

{{-- resources/views/components/app/datepicker.blade.php --}}
<x-jalali-datepicker
    :wire:model="$attributes->get('wire:model')"
    :jalali="$jalali"
    :range="$range"
    :multiple="$multiple"
    export-calendar="gregorian"
    export-format="Y-m-d"
    {{ $attributes }} />

That wrapper is the swap-out point if we later replace the package with Flatpickr + jalaali-js, and it is the one place where the {start, end} and array payload shapes get normalized for the rest of the app.

Compatibility checklist before the first commit:

  • Pin the exact version in composer.json and commit composer.lock; do not use a floating ^ constraint in a shared codebase while the package is at 0 stars.
  • Confirm PHP and Livewire constraints in the installed tag's composer.json match our runtime, not just what the README claims.
  • Verify the bundled script actually resolves in our environment (staging behind CSP, not just local).
  • min-date, max-date, and disabled-dates must be passed in input-format (default Y/m/d for Jalali), not export-format. Getting this backwards is silent — the limits just stop applying.
  • Normalize server-side on receipt rather than trusting the display string: parse, validate, and cast to ->toDateString() before persisting.

Sequencing.

  1. Spike (1–2 days): throwaway branch, one rendered component on our exact Laravel/Livewire/PHP combination, one range and one multiple instance, one save round-trip into a Gregorian column. This produces our real documentation.
  2. Pilot: one non-customer-facing screen — admin filter bar, settings page, or an internal form. Not checkout, not a compliance field.
  3. Wrapper + normalization helper extracted from the pilot, with the payload shapes documented in the repo.
  4. Config publish and i18n: php artisan vendor:publish --tag=datepicker-config, set default_calendar, formats.input/formats.export, first_day_of_week (6 for Saturday in Jalali), theme.
  5. Feature rollout: range filters → min/max and disabled dates → multiple selection with max-selections.
  6. Broaden only after the pilot has run a full release cycle without date-handling defects.

Fallback plan, written before rollout: keep the wrapper thin enough that swapping in a first-party Flatpickr + jalaali-js implementation is a one-file change, and keep morilog/jalali (already an indirect dependency) as the server-side converter either way.

Operational Impact

Maintenance. This is the dominant cost. Zero stars and zero dependents mean no community to absorb upgrades, triage issues, or notice breakage. Budget an explicit named owner for the wrapper component and a "fork in pocket" posture — MIT licensing makes forking cheap, which is precisely why the vendor risk is survivable but must be pre-approved rather than improvised. Expect a recurring upgrade event each time Laravel ships a major, since the package tracks Laravel majors as its own version lines. Add the package to the dependency-review watchlist (release notes, advisories, dist/ rebuild on tag) as a standing item.

Support. Treat as unsupported upstream. Our team is first-line. Write a one-page internal runbook at pilot time covering: install per Laravel line, the two publish/asset behaviors (bundled vs published), the three payload shapes, the input-format vs export-format trap on min/max/disabled, and the known Jalali leap-year edge. The upstream README's "Releasing a new version" section is telling — it documents the maintainer's manual bump/rebuild/tag ritual, which is exactly the process most likely to break the dist/datepicker.js sync we depend on.

Scaling. Per-instance cost is an Alpine component plus a small date library; fine at the tens-of-inputs scale of a typical form or filter bar. The scaling hazard is loops — a table of 200 rows each rendering a picker will inflate DOM and hydration cost, and Livewire's DOM diffing will reuse picker state across rows unless every instance carries a stable wire:key. Paginate, or render the picker lazily on edit. Server-side helpers are pure PHP with no I/O, so conversion cost is negligible at any volume we would realistically hit.

Failure modes to instrument for:

  • Version mismatch on upgrade — a Laravel major bump or composer update pulling a tag whose PHP/Livewire constraints no longer match, producing a hard boot failure or a silently dead component.
  • Asset failure — script 404 or CSP block leaves a visually normal but non-interactive input; users type free text and the server receives something unparseable. Add a client-side smoke assertion or a synthetic check on the pages that use it.
  • Payload shape confusion — code assuming a scalar where range returns {start, end} or multiple returns an array; validation passes on a string-typed rule and fails at persist time.
  • Date-boundary off-by-one — browser conversion in local time vs a server converting in UTC, plus Jalali leap-year boundaries (Esfand 29 vs 30).
  • Constraint drift — min-date/max-date/disabled-dates authored in export-format instead of input-format, so limits silently no-op.
  • Loop state bleed — missing wire:key reusing the wrong picker's selection across rows.
  • Abandonment — no patch path for a future advisory; mitigated only by the pre-scoped fork.

Ramp-up. Developer ramp-up is genuinely low: a Laravel/Livewire engineer is productive on a single date field inside a day, and the attribute table in the README is adequate for the common cases. The real ramp-up cost is domain, not tooling — Jalali month lengths, leap years, the Saturday-start week, RTL layout, and Persian locale strings. Budget a short working session with a Persian-speaking stakeholder before the pilot ships, and write unit tests around both the PHP conversion helpers and the full save path for a leap-year date and a range spanning a month boundary. Those tests are cheap now and are the only durable defense given the absence of upstream coverage.

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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table