Package Exports
- versynch
- versynch/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (versynch) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
🔄 versynch
The most reliable auto-update & version sync solution for React + PWA apps
🎉 NOW LIVE ON NPM! Install with: npm install versynch
versynch is a comprehensive solution for managing version control and force-updating outdated React applications. It solves the problem of users getting stuck with stale cached versions, especially in PWA (Progressive Web App) environments.
✨ Features
Force Update Detection System
- Detects legacy versions automatically on app load
- Forces immediate cache clearing and update for severely outdated versions
- Shows update notifications and handles the process smoothly
- Configurable minimum build thresholds for enforcing updates
- Safe implementation for apps without previous versioning
Version Management System
- Full version tracking with semantic versioning support
- Build numbers for precise version control
- Automatic detection of users on old versions
- Automated build number generation for CI/CD workflows
Smart Update Experience
- Detects user activity to avoid interrupting work
- Background updates when users are inactive
- Configurable countdown timers and postpone options
Reliable Cache Busting
- Aggressive cache clearing for legacy users
- Service worker unregistration for clean slate
- Timestamp-based URL parameters for cache busting
🚀 Installation
The package is now available on npm! Install it using your preferred package manager:
# Using npm
npm install versynch
# Using yarn
yarn add versynch
# Using pnpm
pnpm add versynch📋 Requirements
- React 16.8+ (uses hooks)
- TypeScript (optional but recommended)
- For full functionality, your app should use service workers
🧩 Usage
Basic Setup
import React from 'react';
import { ForceUpdateDetector, UpdateNotification } from 'versynch';
const App: React.FC = () => {
// Your app's current version
const appVersion = "2.1.0";
const buildNumber = 210;
return (
<>
<ForceUpdateDetector
version={appVersion}
build={buildNumber}
minBuildToForceUpdate={200} // Users with builds below 200 will be forced to update
onForceUpdate={() => console.log("Force updating...")}
>
<div className="app-content">
{/* Your app content */}
</div>
<UpdateNotification
version={appVersion}
build={buildNumber}
/>
</ForceUpdateDetector>
</>
);
};
// For apps without previous versioning
const FirstTimeVersioningApp: React.FC = () => {
// Initial version for an app that didn't have versioning before
const appVersion = "1.0.0";
const buildNumber = 100;
return (
<>
<ForceUpdateDetector
version={appVersion}
build={buildNumber}
minBuildToForceUpdate={0} // Set to 0 to avoid forcing updates on first implementation
onForceUpdate={() => console.log("Processing update...")}
>
<div className="app-content">
{/* Your app content */}
</div>
<UpdateNotification
version={appVersion}
build={buildNumber}
/>
</ForceUpdateDetector>
</>
);
};
export default App;Automated Build Numbers
versynch includes tools to automatically generate build numbers in your CI/CD pipelines:
import React from 'react';
import { ForceUpdateDetector, UpdateNotification } from 'versynch';
import { BUILD_INFO } from './buildInfo'; // Auto-generated file
const App: React.FC = () => {
// App version info is imported from auto-generated buildInfo.ts
const { version, buildNumber } = BUILD_INFO;
return (
<>
<ForceUpdateDetector
version={version}
build={buildNumber}
minBuildToForceUpdate={2025060100000} // Force update for builds before June 1, 2025
onForceUpdate={() => console.log(`Updating to ${version}...`)}
>
<div className="app-content">
{/* Your app content */}
</div>
<UpdateNotification
version={version}
build={buildNumber}
/>
</ForceUpdateDetector>
</>
);
};
export default App;To automatically generate build numbers in your CI/CD pipeline:
Add a build step that runs the provided script:
node scripts/generate-build-number.jsImport the auto-generated build info in your app
For detailed instructions and examples, see Automated Build Documentation and GitHub Actions Examples.
Using the hooks directly
import React from 'react';
import { useVersionManager, useCacheUpdateManager } from 'versynch';
const AppVersionInfo: React.FC = () => {
const {
currentVersion,
currentBuild,
isUpdateAvailable,
isForceUpdate,
forceUpdate
} = useVersionManager({
version: '2.1.0',
build: 210
});
const {
isUpdateInProgress,
countdownSeconds,
handleUpdate,
postponeUpdate
} = useCacheUpdateManager({
isUpdateAvailable,
onUpdateConfirmed: forceUpdate
});
return (
<div>
<h2>Current Version: {currentVersion}</h2>
<p>Build: {currentBuild}</p>
{isUpdateAvailable && (
<div>
<p>Update available! Installing in {countdownSeconds} seconds.</p>
<button onClick={handleUpdate}>Update now</button>
<button onClick={postponeUpdate}>Later</button>
</div>
)}
</div>
);
};Service Worker Integration
For the best experience, enhance your service worker with version broadcasting:
// In your service worker (sw.js)
const APP_VERSION = '2.1.0';
const BUILD_NUMBER = 210;
// On activation, notify all clients
self.addEventListener('activate', (event) => {
event.waitUntil(
self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage({
type: 'SW_UPDATED',
version: APP_VERSION,
timestamp: Date.now()
});
});
})
);
});⚙️ API Reference
Components
<ForceUpdateDetector>
Core component that detects outdated app versions and forces updates.
<ForceUpdateDetector
version="2.1.0" // Current app version
build={210} // Current build number
minBuildToForceUpdate={150} // Min build number that's acceptable
updateDelay={3000} // Delay before forcing update (ms)
onForceUpdate={() => {}} // Callback when force update begins
onUpdateAvailable={() => {}} // Callback when update detected
onUpdateComplete={() => {}} // Callback when update finishes
showFallbackUI={true} // Whether to show loading UI
fallbackUI={<CustomLoader />} // Custom loading component
>
{/* Your app content */}
</ForceUpdateDetector><UpdateNotification>
Component that shows a notification when an update is available.
<UpdateNotification
version="2.1.0" // Current app version
build={210} // Current build number
countdownDuration={60000} // Countdown time before auto-update (ms)
maxPostponeCount={3} // Max times user can postpone update
show={true} // Whether to show notification
renderNotification={(props) => (
// Custom notification UI
<CustomNotification {...props} />
)}
/>Service Worker Integration
versynch provides tools for integrating with service workers to enhance the update process:
import {
registerServiceWorker,
checkForServiceWorkerUpdate,
activateServiceWorkerUpdate,
BUILD_INFO
} from 'versynch';
function App() {
useEffect(() => {
// Register service worker with version info
registerServiceWorker();
// Listen for updates
window.addEventListener('serviceWorkerUpdateAvailable', () => {
console.log('Update available!');
});
}, []);
const handleCheckForUpdates = async () => {
const hasUpdate = await checkForServiceWorkerUpdate();
if (hasUpdate) {
console.log('Update available!');
}
};
const handleApplyUpdate = async () => {
await activateServiceWorkerUpdate();
// Page will reload with new version
};
return (
<ForceUpdateDetector
version={BUILD_INFO.version}
build={BUILD_INFO.buildNumber}
minBuildToForceUpdate={2025060100000}
>
{/* Your app content */}
</ForceUpdateDetector>
);
}See Automated Build Documentation for more details.
Hooks
useVersionManager(options)
Manages version information and update processes.
const {
currentVersion, // Current stored version
currentBuild, // Current stored build
isUpdateAvailable, // Whether update is available
isForceUpdate, // Whether force update is needed
lastChecked, // Timestamp of last check
forceUpdate, // Function to force update
checkForUpdates // Function to check for updates
} = useVersionManager({
version: '2.1.0', // Current app version
build: 210, // Current build number
minBuildToForceUpdate: 200, // Force update for users with builds below 200
onForceUpdate: () => {}, // Callback when force update begins
onUpdateAvailable: () => {}, // Callback when update available
onUpdateComplete: () => {} // Callback when update completes
});useCacheUpdateManager(options)
Manages cache update processes with user activity detection.
const {
isUpdateInProgress, // Whether update is in progress
isPostponed, // Whether update is postponed
postponeCount, // Number of times update postponed
countdownSeconds, // Seconds left in countdown
handleUpdate, // Function to handle update now
postponeUpdate, // Function to postpone update
startAutoUpdateProcess // Start automatic update process
} = useCacheUpdateManager({
isUpdateAvailable, // Whether update is available
onUpdateConfirmed: () => {}, // Callback when update confirmed
onUpdatePostponed: () => {}, // Callback when update postponed
countdownDuration: 60000, // Countdown duration (ms)
inactivityThreshold: 30000, // User inactivity threshold (ms)
maxPostponeCount: 3 // Max times user can postpone
});🛠 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
🔍 Troubleshooting
Having issues with continuous update loops or other problems? Check out our troubleshooting guide for solutions to common issues.
Key things to check:
- Ensure
minBuildToForceUpdateis configured correctly (see troubleshooting doc) - Verify your service worker integration
- Check for proper error handling in update processes
📄 License
MIT
🙌 Credits
Created by Nchimunya Munyama