Weave Code
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

Neon Laravel Package

nette/neon

Human-friendly configuration format for PHP. NEON is a structured data language similar to YAML/JSON, with neat syntax for arrays and objects, comments, and multiline strings. Includes fast parser and emitter, used across Nette and beyond.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require nette/neon
    

    Ensure PHP 8.2+ is used (v3.4.8+ requirement).

  2. First Use Case: Decode a NEON file into a PHP array:

    use Nette\Neon\Neon;
    
    $config = Neon::decodeFile(__DIR__.'/config.neon');
    // Example config.neon:
    // services:
    //     mail:
    //         driver: smtp
    //         host: mail.example.com
    
  3. Encode Data Back to NEON:

    $neonString = Neon::encode([
        'services' => [
            'mail' => [
                'driver' => 'smtp',
                'host' => 'mail.example.com',
            ],
        ],
    ]);
    
  4. Key Files:

    • vendor/nette/neon/src/ for core classes.
    • vendor/nette/neon/tests/ for edge-case examples.

Implementation Patterns

Workflows

  1. Configuration Loading:

    • Replace Laravel’s config() helper for non-JSON/YAML configs:
      $config = Neon::decodeFile(config_path('app.neon'));
      config(['app' => $config['app']]);
      
    • Use Neon::decodeFile() for atomic reads (avoids race conditions in deployments).
  2. Dynamic Configuration:

    • Merge NEON configs with Laravel’s config():
      $neonData = Neon::decode($request->input('config_neon'));
      config(['feature_flags' => array_merge(config('feature_flags'), $neonData)]);
      
  3. Validation & Linting:

    • Integrate the built-in linter (v3.3.1+) in CI:
      use Nette\Neon\Linter;
      
      $errors = Linter::lintFile(__DIR__.'/config.neon');
      if (!empty($errors)) {
          throw new \RuntimeException("NEON lint errors: " . implode("\n", $errors));
      }
      
  4. Service Container Integration:

    • Bind NEON-decoded configs to Laravel’s container:
      $this->app->singleton('config.neon', function () {
          return Neon::decodeFile(config_path('services.neon'));
      });
      

Integration Tips

  • Hybrid Configs: Use NEON for human-edited configs (e.g., config/services.neon) and JSON/YAML for API-driven configs.
  • Caching: Cache decoded NEON configs in Laravel’s cache:
    $cachedConfig = cache()->remember('neon-config', now()->addHour(), function () {
        return Neon::decodeFile(config_path('app.neon'));
    });
    
  • Error Handling: Wrap Neon::decode() in try-catch for malformed NEON:
    try {
        $data = Neon::decode($neonString);
    } catch (\Nette\Neon\Exception $e) {
        report($e);
        return response()->json(['error' => 'Invalid NEON'], 400);
    }
    
  • Multiline Strings: Leverage NEON’s """ syntax for SQL queries or long text:
    queries:
        create_table: """
        CREATE TABLE users (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(255)
        )
        """
    

Gotchas and Tips

Pitfalls

  1. UTF-8 Strictness:

    • NEON throws exceptions on invalid UTF-8 (v3.2.0+). Validate files with:
      if (!mb_check_encoding($neonString, 'UTF-8')) {
          throw new \InvalidArgumentException('NEON must be UTF-8 encoded');
      }
      
  2. PHP 8.2+ Requirement:

    • v3.4.8+ requires PHP 8.2+. Use v3.3.x for older PHP versions (but lose phpDoc improvements).
  3. Breaking Changes:

    • v3.4.0 removed on/off syntax and \x** literals. Update legacy NEON files:
      # Before (deprecated)
      enabled: on
      hex_value: \xFF
      
      # After
      enabled: true
      hex_value: 0xFF
      
  4. Big Integers:

    • Integers larger than PHP_INT_MAX are decoded as strings (v3.4.3). Handle with:
      $value = Neon::decode($neonString);
      if (is_string($value) && ctype_digit($value)) {
          $value = gmp_init($value); // Use GMP for large integers
      }
      
  5. Circular References:

    • NEON does not support circular references (unlike JSON). Use serialize()/unserialize() for complex objects.
  6. Indentation Sensitivity:

    • NEON is whitespace-sensitive (unlike JSON). Use consistent indentation (e.g., 4 spaces):
      # Correct
      services:
          mail:
              driver: smtp
      
      # Incorrect (mixed tabs/spaces)
      services:
          mail:
          driver: smtp
      

Debugging Tips

  1. Linting Errors:

    • Run the linter to catch syntax issues early:
      php -r "(new Nette\Neon\Linter)->lintFile('config.neon');"
      
  2. AST Inspection:

    • Use the Traverser to debug complex NEON structures:
      use Nette\Neon\Neon;
      use Nette\Neon\Traverser;
      
      $ast = Neon::parse($neonString);
      $traverser = new Traverser();
      $traverser->onEnterNode(function ($node) {
          dump(get_class($node), $node->getName());
      });
      $traverser->traverse($ast);
      
  3. Encoding Quirks:

    • Control characters (e.g., \n, \t) are escaped in output. Use raw strings for multiline:
      # Multiline string (preserves newlines)
      description: """
      This is a
      multiline string.
      """
      
  4. Performance:

    • For large NEON files, use Neon::decodeFile() with a stream wrapper:
      $data = Neon::decodeFile('php://temp', function () {
          yield file_get_contents('large-config.neon');
      });
      

Extension Points

  1. Custom Node Types:

    • Extend Nette\Neon\Node\Node to support domain-specific syntax:
      class LaravelNode extends Node {
          public function getLaravelValue(): mixed { ... }
      }
      
  2. Encoder Flags:

    • Customize encoding with flags (v3.3.1+):
      $neon = Neon::encode($data, Neon::BLOCK_ARRAY, Neon::INDENT_4_SPACES);
      
  3. Traverser Callbacks:

    • Modify the AST during parsing:
      $traverser = new Traverser();
      $traverser->onEnterNode(function (Node $node) {
          if ($node instanceof ArrayNode) {
              $node->setIndentation(2); // Force 2-space indent
          }
      });
      $traverser->traverse($ast);
      
  4. Linter Rules:

    • Add custom linting rules by extending Nette\Neon\Linter:
      class CustomLinter extends Linter {
          protected function checkCustomRules(Node $node): void {
              // Implement custom validation logic
          }
      }
      
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony