{"id":46433,"library":"spring-river","title":"Spring River","description":"Spring River is an experimental, asynchronous queue-based microservices framework for Node.js (v1.0.36). It implements the Rapids/Rivers/Ponds pattern, where 'rivers' produce solutions and 'springs' generate needs, communicating via AMQP (e.g., RabbitMQ). Key differentiators include a simple bootstrap approach inspired by ZEIT's Micro, built-in predicate decorators for packet filtering, and environment-based AMQP address configuration. However, the project is marked as experimental and has not seen updates since 2017, making it unsuitable for production use.","status":"abandoned","version":"1.0.36","language":"javascript","source_language":"en","source_url":"https://github.com/gtramontina/spring-river","tags":["javascript"],"install":[{"cmd":"npm install spring-river","lang":"bash","label":"npm"},{"cmd":"yarn add spring-river","lang":"bash","label":"yarn"},{"cmd":"pnpm add spring-river","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"AMQP client library required for RabbitMQ connectivity","package":"amqplib","optional":false},{"reason":"Optional for loading AMQP address from .env file","package":"dotenv","optional":true}],"imports":[{"note":"No explicit import needed; the 'river' binary is used via scripts.start in package.json and exports a function from your module.","wrong":"const river = require('spring-river').river","symbol":"river","correct":"module.exports = (packet, publish) => { ... }"},{"note":"No explicit import needed; the 'spring' binary is used via scripts.start and exports a function that takes only a publish callback.","wrong":"const spring = require('spring-river').spring","symbol":"spring","correct":"module.exports = (publish) => { ... }"},{"note":"Built-in predicates are not exported from main package; import from specific path.","wrong":"const { forbidKeys } = require('spring-river');","symbol":"forbid-keys","correct":"const forbidKeys = require('spring-river/predicates/forbid-keys');"},{"note":"Package uses CommonJS, not ESM. Import from predicates subpath.","wrong":"import { requireKeys } from 'spring-river';","symbol":"require-keys","correct":"const requireKeys = require('spring-river/predicates/require-keys');"}],"quickstart":{"code":"// package.json\n{\n  \"main\": \"index.js\",\n  \"name\": \"my-river\",\n  \"scripts\": { \"start\": \"river\" }\n}\n\n// index.js\nmodule.exports = (packet, publish) => {\n  packet.solution = 42;\n  publish(packet);\n};\n\n// Run ADDRESS=amqp://localhost npm start","lang":"javascript","description":"Shows how to create a simple 'river' microservice that adds a solution to a packet and publishes it via AMQP."},"warnings":[{"fix":"Consider using an alternative like RapidsRivers (Python/Java) or a more modern Node.js microservices framework.","message":"Package has not been updated since 2017 and is considered abandoned.","severity":"deprecated","affected_versions":"*"},{"fix":"Ensure a RabbitMQ instance is running and ADDRESS is set correctly before starting services.","message":"The library requires RabbitMQ or another AMQP-compatible broker. No fallback for missing broker.","severity":"breaking","affected_versions":"*"},{"fix":"Use exact path: require('spring-river/predicates/forbid-keys')","message":"Predicates are not exported from the main package; they must be required via full path (e.g., 'spring-river/predicates/forbid-keys').","severity":"gotcha","affected_versions":"*"},{"fix":"Do not attempt to require('spring-river/river') or require('spring-river/spring') in code.","message":"The 'river' and 'spring' binaries are not actual modules; they are CLI scripts invoked via npm start. Direct require will fail.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"search_vec":"'2017':75 'address':60 'amqp':32,59 'approach':41 'asynchron':8 'base':11,58 'bootstrap':40 'built':48 'built-in':47 'communic':30 'configur':61 'decor':51 'differenti':36 'e.g':33 'environ':57 'environment-bas':56 'experiment':7,68 'filter':54 'framework':13 'generat':28 'howev':62 'implement':18 'includ':37 'inspir':42 'javascript':82 'key':35 'make':76 'mark':66 'micro':46 'microservic':12 'need':29 'node.js':15 'packet':53 'pattern':21 'predic':50 'produc':24 'product':80 'project':64 'queue':10 'queue-bas':9 'rabbitmq':34 'rapids/rivers/ponds':20 'river':2,4,23 'seen':72 'simpl':39 'sinc':74 'solut':25 'spring':1,3,27 'unsuit':78 'updat':73 'use':81 'v1.0.36':16 'via':31 'zeit':44","created_at":"2026-06-07T12:59:54.092832+00:00","updated_at":"2026-06-07T12:59:54.092832+00:00","problems":[{"fix":"const forbidKeys = require('spring-river/predicates/forbid-keys');","cause":"Incorrect import path; forgetting to include '/predicates/'","error":"Error: Cannot find module 'spring-river/predicates/forbid-keys'"},{"fix":"Start RabbitMQ (e.g., docker run -d --name rabbitmq -p 5672:5672 rabbitmq) and set ADDRESS=amqp://localhost before running npm start","cause":"RabbitMQ is not running or ADDRESS is not set","error":"Error: connect ECONNREFUSED 127.0.0.1:5672"},{"fix":"For river: module.exports = (packet, publish) => { ... }. For spring: module.exports = (publish) => { ... }","cause":"Exporting function incorrectly for a 'river' (should accept two arguments) or for a 'spring' (should accept one argument)","error":"TypeError: publish is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/gtramontina/spring-river#readme","github":"https://github.com/gtramontina/spring-river","docs":null,"changelog":null,"pypi":null,"npm":"spring-river","openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}