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

Code Mirror Bundle Laravel Package

nitrado/code-mirror-bundle

A Symfony bundle that integrates the CodeMirror code editor into PHP applications, simplifying asset setup and configuration so you can add syntax-highlighted, customizable code editing to forms and templates with minimal effort.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony2 bundle, not a Laravel package. There is no service provider, no config/code-mirror.php, and its Composer constraints will almost certainly conflict with a modern Laravel install (Symfony 2.x-era symfony/framework-bundle, PHP 5.x/7.0-era code). Treat this repository as a reference implementation to port, not a dependency to composer require. Budget an afternoon, not five minutes.

Where to look first, in this order:

  1. composer.json – confirm the Symfony/PHP constraints. This tells you immediately whether it can coexist with anything you run today (it usually can't).
  2. DependencyInjection/Configuration.php and SolutionCodeMirrorExtension.php – this is the entire configuration surface: default mode, theme, height, whether assets are auto-included.
  3. Form/Type/ – the bundle's value is almost certainly a CodeMirrorType (or a code_mirror widget option) that wraps a textarea.
  4. Resources/views/ – the Twig template that emits the <textarea> plus the CodeMirror.fromTextArea(...) init script.
  5. Resources/public/ – whether CodeMirror itself is vendored (old bundles shipped it) or expected from elsewhere.

Minimal Symfony2 wiring (for reference when porting):

# app/config/config.yml
solution_code_mirror:
    mode: yaml
    theme: default
    height: 400px
$builder->add('template', CodeMirrorType::class);

Your actual first use case in Laravel is the one this bundle was built for: an admin form where users edit JSON/YAML/Twig/Markdown in a plain <textarea>, and you want syntax highlighting, line numbers, and bracket matching. The port is:

npm install codemirror
{{-- resources/views/components/code-editor.blade.php --}}
<div wire:ignore x-data x-init="
    const cm = CodeMirror.fromTextArea($refs.ta, { mode: '{{ $mode }}', lineNumbers: true, theme: '{{ $theme }}' });
    cm.setSize(null, '{{ $height }}');
    cm.on('change', () => $refs.ta.value = cm.getValue());
">
    <textarea x-ref="ta" name="{{ $name }}" {{ $attributes }}>{{ $slot }}</textarea>
</div>

That single Blade component replaces the whole bundle. Everything below assumes you are either doing that port or maintaining a legacy Symfony2 app that already has it installed.

Implementation Patterns

Legacy Symfony2 (existing app):

  • Form type as the primary interface. Use the bundle's form type rather than hand-writing <script> tags, so mode/theme come from config and you get consistent markup. Override per-field with the type's options if it exposes them (mode, theme, height) instead of editing the bundle.
  • Twig form themes. If the bundle ships a form theme, register it once in config.yml under twig.form_themes rather than calling form_widget with custom markup per view. One theme, applied globally, is the maintenance-light path.
  • Asset inclusion. Old bundles auto-inject <script>/<link> via a Twig extension or a kernel.request listener. If you have a proper asset pipeline (Assetic, Webpack Encore), disable the bundle's auto-include and load CodeMirror once in your base layout to avoid duplicate copies on every page.

Laravel port (what you'll actually build):

  • One Blade component, one Alpine directive. Keep the CodeMirror.fromTextArea call inside a small Alpine component so it works identically in plain Blade, Livewire, and dynamically-added rows. Do not scatter init scripts through views.
  • Sync the textarea on change, not on submit. cm.on('change', ...) writing back to the textarea is more robust than a submit handler — it survives Livewire's wire:model round-trips and browser back/forward. If you rely on save()-on-submit, any Livewire re-render will silently drop edits.
  • Collection / dynamic rows. When rows are added by JS or Livewire (wire:ignore + $nextTick), re-run CodeMirror.fromTextArea on the new textarea. Keep an init function you can call repeatedly; guard with if (el.dataset.cmInit) return;.
  • Modes and addons are separate imports. Import only the modes you use (@codemirror/lang-json, or in v5 codemirror/mode/yaml/yaml). A single "load everything" import is what bloats the bundle; the Symfony bundle used to sidestep this by shipping prebuilt mode/ files, which you should not copy.
  • Server-side validation is unchanged. The editor is a textarea; validate with Validator::make / FormRequest exactly as before. The bundle never touched validation and neither should your component.
  • Reusable option bag. Expose mode, theme, height, readonly, lineNumbers as component props with sane defaults, so mode="yaml" is the only thing a view author writes.
  • Progressive enhancement. Render a real <textarea> first; if JS fails or Vite hasn't loaded, the form still submits. This is the main thing the old bundle got right — preserve it.

Gotchas and Tips

  • It is not a Laravel package, and it is effectively unmaintained. Zero dependents and a Symfony2 target mean no security patches, no CodeMirror upgrades, no support for modern Symfony or PHP. Don't put it in a new composer.json; vendor the idea, not the code.
  • CodeMirror 5 vs 6 is a hard split. This bundle predates v6 entirely (CodeMirror.fromTextArea is v5 API). If you follow its examples while installing codemirror@6, nothing will work — v6 is EditorView/EditorState with no fromTextArea. Pick v5 (simple, drop-in, deprecated) or v6 (ESM, tree-shaken) deliberately and don't mix tutorials.
  • fromTextArea requires the element to be in the DOM and visible. Initializing inside a hidden tab, modal, or collapsed x-show="false"} panel yields a zero-width editor. Call cm.refresh() after showing, or defer init until visible.
  • Textarea value is not automatically synced in every setup. This is the single most common "my edits disappeared" bug. Always wire change → textarea.value.
  • Escaping in the init script. Values like a YAML mode string are fine, but if you ever pass user-controlled content into the JS options block you get an XSS hole. Pass options via data-* attributes and read them with el.dataset, not via string interpolation into <script>.
  • CSP. Inline x-init/<script> blocks break under a strict script-src. If you have CSP, move init into a compiled JS file and bind by data-code-editor attribute rather than inline handlers.
  • Config quirks from the bundle. Old Symfony bundles read config at container compile time, so changing mode in config.yml may require cache:clear. Don't expect per-request flexibility; if you need per-form modes, that's an argument for the component port.
  • Asset duplication. If the bundle auto-includes CodeMirror and your layout does, you get two copies and confusing "duplicate instance" behavior. Grep rendered HTML for two codemirror script tags before debugging anything else.
  • Testing. CodeMirror is hard to drive with plain HTTP tests. For Laravel, assert the textarea content after a request (Dusk/Panther for the JS layer); in Symfony, use Panther rather than the default crawler, which sees only the textarea — which is honestly the right thing to assert anyway.
  • Extension points if you must fork. The only pieces worth lifting are (a) the form-type-to-options mapping and (b) the textarea-first progressive-enhancement markup. Skip the DI extension entirely — a Laravel config file is three lines.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle