Two-Way Binding in Vanilla JavaScript
Introduction
Two-Way Binding in Vanilla JavaScript

Introduction
Two-way binding is a powerful feature commonly found in frameworks like Angular, Vue, and React (with state management libraries). It allows real-time synchronization between the UI and the underlying data model. This blog explores how we can implement two-way binding using plain JavaScript without any frameworks.
What is Two-Way Binding?
Two-way binding ensures that changes in the UI elements (like input fields) are automatically reflected in the data model and vice versa. This eliminates the need to manually update the DOM whenever the state changes.
Implementing Two-Way Binding in JavaScript
Let’s dive into an example where we achieve two-way binding between an input field and a paragraph element.
HTML Structure (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="index.css">
<title>Two-Way Binding Example</title>
</head>
<body>
<h1>Two-Way Binding Like a Framework</h1>
<input id="input" type="text" placeholder="Type something..." />
<p id="paragraph"></p>
<script src="./index.js"></script>
</body>
</html>
JavaScript Logic (index.js)
const input = document.getElementById("input")
const paragraph = document.getElementById("paragraph")
const state = { value: "Hi" }
// paragraph.innerText = "Hi"
// call function
enableTwoWayBind(input, state)
function enableTwoWayBind(input, state) {
// sync intially input and state variable
input.value = state.value
paragraph.textContent = input.value
// on state variable update
Object.defineProperty(state, 'value', {
get() {
return input.value
},
set(newVal) {
input.value = newVal
// update ui
paragraph.textContent = newVal
// input.dispatchEvent(new Event('input'));
return this
}
})
}
input.addEventListener('input', () => {
const newVal = input.value
state.value = newVal
paragraph.textContent = newVal
// let inputData = e.target.value
// paragraph.innerText = inputData
console.log(newVal)
})
// update with state value to input value
state.value = "subcribe"
// // upadte input value to state value
input.value = 'shashikant'
input.dispatchEvent(new Event('input'))
How It Works
- Initial State Sync:
- The
state.valueis initialized with "Hi". - The input field and paragraph are updated to reflect the initial state.
- Reactivity using
Object.defineProperty:
- When
state.valueis updated, it triggers a setter that updates the UI.
- Event Listener for Input Changes:
- Whenever the user types in the input field, the
inputevent updatesstate.value, which in turn updates the paragraph text.
Key Benefits
- Eliminates Manual DOM Updates: The UI automatically updates whenever the state changes.
- Provides Reactivity Without a Framework: Achieves a fundamental concept of modern frameworks using vanilla JavaScript.
- Lightweight and Efficient: No external dependencies are required.
Conclusion
This approach demonstrates how two-way binding can be implemented with pure JavaScript. While frameworks simplify this process, understanding the core mechanism helps in optimizing and customizing UI interactions effectively.
Would you implement this in your next project? Let me know in the comments!
메타데이터
- post_id
- 97c346c9f2e4
- slug
- two-way-binding-in-vanilla-javascript-97c346c9f2e4
- url
- https://medium.com/@shashi94goswami/two-way-binding-in-vanilla-javascript-97c346c9f2e4
- canonical_url
- https://medium.com/@shashi94goswami/two-way-binding-in-vanilla-javascript-97c346c9f2e4
- author_url
- https://medium.com/@shashi94goswami
- status
- ok
- fetched_at
- 2026-07-13 06:23:13