The film begins with a successful horror author returning to his hometown of Willowpoint Falls. Stopping at a cemetery to visit a pair of gravestones, he begins to tell his driver their story. On Halloween 1962, 9-year-old Franklin "Frankie" Scarlatti (Lukas Haas) tells a scary story to his classmates. Afterwards, two of school jokesters Donald (Jared Rushton) and Louie (Gregory Levinson) take Frankie's hat and toss it on a shelf in the cloak room. They let Frankie know where it is and then lock him in in the cloak room as he tries to get it back.
At nightfall, Frankie is still locked in the cloak room and sees the ghost of a little girl re-enact her death. Afterwards, a darkened figure enters the cloak room and begins to unscrew the metal vent unaware that Frankie is still hiding in the room. A rat startles Frankie which alerts the stranger to his presence. The stranger attacks Frankie and he loses consciousness taking him into a dreamlike state where he speaks to the ghost girl. Frankie is revived by his father giving him CPR and rushed to the hospital. Police find and arrest the black school janitor Harold Williams who was found drunk in the basement.
Frankie is soon released from the hospital and enjoys a comfortable recovery with his family. His brother Geno, brings a newspaper home which proclaims Frankie to be a star. Geno is reprimanded for making an inappropriate remark and the newspaper is thrown away. Secretly, Frankie finds the newspaper and reads the story regarding his attack which coincidentally links him to an on-going 10 year investigation into the deaths of 11 other children at the hands of a serial killer. Within the same article, he learns the name of the ghost - Melissa Ann Montgomery (Joelle Jacobi). Soon, Frankie sees the ghost of Melissa frequently and he befriends her. Her only request is that he help her find her mother.
When he returns to school, Frankie finishes removing the grate cover on the airvent in the cloakroom and removes an odd assortment of children's objects. He singles out two things, a hairclip - which he assumes to belongs to Melissa as he saw something hard and shiny fly off her hair and drop into the grate during her struggle - and an old high school class ring. Frankie cannot figure out the significance of anything he found in the grate. A few more weeks pass and the seasons change.
One day, Frankie overhears a conversation between his father and the chief of police. The chief readily admits that Mr. Williams is probably a scapegoat for the murders. The chief also explains that blood found within the cloakroom links that location to the murder of Melissa Montgomery - a fact not released to the press. In a flash, Frankie figures out that the killer came back for his class ring which he dropped into the airvent the night he killed Melissa.
Unbeknownst to Frankie, the ring has fallen out of his pocket in his bedroom several days earlier (and picked up by Geno). Frankie relays his theories to family friend Phil. Several days later, Frankie is lured out to the cliffs by Donald and Louie and encounters a lady in white clothing inside an old abandoned cottage. All three kids run out of the house scared but Frankie realizes that she may be Melissa's mother and tries to explain the situation to Geno (who has come looking for him due to the late hour). Geno does not believe him but now understands the origin of the ring he found. Although he does not tell Frankie that he found the ring.
Melissa's ghost haunts Frankie in a non-threatening way. She appears one night and even Geno sees her. Suddenly, both boys follow her as she re-creates her death scene at 10pm (it is implied that this happens every night). They are late arriving at the school and by the time they get to the front door, her ghost is seen being carried down the stairs (presumably dead) and back out of the school. This time, Frankie follows her but Geno is incapacitated by a thorn in the foot and cannot give chase. Alone, Frankie follows the body (that is being carried by an unseen person) out to the cliffs. There, Frankie sees that at the last minute, Melissa regains consciousness, screams and is thrown over the cliffs alive. Afterwards, Melissa's mother runs out of the old white cottage calling for her daughter. She sees Melissa's body at the foot of the cliffs and then throws herself over the edge. Geno finally catches up with a very startled Frankie and they both go home.
Harold Williams, the black school janitor, who got drunk while watching a ballgame in the school basement on the night of Frankie's assault, is accused of the attempted murder of Frankie and the murder of Melissa and ten other children. This sets off instances of outrage in the community but Angelo Scarlatti (Alex Rocco), Frankie's father, believes Williams' claim of innocence upon failure to link the janitor to Frankie's assault and the fact that Williams is also a father. Williams is later freed when a grand jury decides against going to trial due to insufficient evidence, but he is then murdered by the mother of one of the victims (who believes him to be guilty).
Meanwhile, Geno continues to investigate the ring that Frankie found in the vent. His father has an old trunk full of old sentimental objects and he notices that his father owns an identical class ring from the same school year. He realizes that the killer may be in the same graduating class as his father. Geno compares the initials on the old ring with his father's yearbook, and discovers that the murderer is family friend Phil. He frantically runs to tell his father and the police chief. Frankie, who is with Phil at that time, figures out the truth when Phil is whistling "Did You Ever See a Dream Walking" (Melissa's song) and unwittingly tips off Phil. Phil attempts to attack Frankie, but he escapes and runs to the cliffs. Phil chases him and admits to being the killer, but claims he had no idea he was attacking Frankie on Halloween. He explains that he wouldn't have done it had Frankie not been wearing his Halloween mask as he cares about him a great deal. Phil attacks Frankie by strangling him and demands the whereabouts/return of the ring. Suddenly he's struck from behind by an unseen person and both Frankie and Phil collapse.
Frankie then awakens in the well-preserved bedroom (presumably the old cottage) which had been Melissa's, under the care of the woman who saved him, Amanda Harper (Katherine Helmond). She reveals that she is Melissa's aunt and has been despondent over the loss of her sister and niece. She also tells Frankie that she set fire to her own house in an attempt to take her own life in order to be reunited with her family, but was rescued from the blaze and subsequently branded the town crazy.
Before she can finish her explanations, Phil sneaks into the cottage, attacks, and murders Harper. Several candles are knocked over during the struggle and a large housefire begins. Phil rescues Frankie from the burning cottage but only to try and throw Frankie off the cliff. Frankie puts up a great struggle and in the end is saved by the ghost of Melissa's mother (the true Lady in White) who scares Phil over the edge of the cliff. Having brought the ghost of Melissa with him, Frankie watches as she and the Lady in White reunite and ascend into the sky.
Frankie attempts to crawl away from the cliff edge but is grabbed around the ankle by a struggling Phil (who's holding onto a lone tree branch). Frankie's father Angelo, Geno, the police, and hunters with scent-tracking dogs arrive. Angelo frees Frankie and tries to save Phil, but at the last minute Phil lets go and falls to his death. With Phil dead, the movie ends with the group watching as the cottage burns down while the snow begins to fall.